/* ---------------------------------------------------------------
   Adeia — the remaining pieces: the dashboard mock in the hero shot,
   the split panel, the FAQ, notes, closing and footer.
   --------------------------------------------------------------- */

/* ---------- the dashboard mock ----------
   Drawn rather than screenshotted, so it stays sharp at any width and
   cannot go stale when the real dashboard changes. */

.mock__stats {
  display: flex;
  gap: 2.5rem;
  flex-wrap: wrap;
  padding-bottom: 1.5rem;
  margin-bottom: 1.25rem;
  border-bottom: 1px solid var(--hair);
}

.mock__stats div {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.mock__stats b {
  font-size: 1.75rem;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.03em;
}

.mock__stats span {
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
}

.mock__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-small);
}

.mock__table th {
  text-align: left;
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--faint);
  padding: 0 1rem 0.75rem 0;
  border-bottom: 1px solid var(--hair);
}

.mock__table td {
  padding: 0.875rem 1rem 0.875rem 0;
  border-bottom: 1px solid var(--hair);
  vertical-align: top;
}

.mock__table tr:last-child td {
  border-bottom: 0;
}

.mock__what {
  display: block;
  color: var(--paper);
  font-size: 0.8125rem;
}

.mock__sub {
  display: block;
  color: var(--faint);
  font-size: var(--t-micro);
  margin-top: 0.25rem;
}

/* The classifier's line, in the cold end of the gradient. A model
   deciding and a person deciding must never look alike. */
.mock__model {
  display: block;
  margin-top: 0.5rem;
  padding-left: 0.625rem;
  border-left: 2px solid var(--cold);
  color: var(--cold);
  font-size: var(--t-micro);
  line-height: 1.4;
}

.mock__when {
  color: var(--faint);
  font-size: var(--t-micro);
  white-space: nowrap;
}

.pill {
  display: inline-block;
  padding: 0.1875rem 0.5625rem;
  border-radius: 999px;
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}

.pill--ran {
  background: var(--ran);
  color: var(--ran-ink);
}
.pill--held {
  background: var(--held);
  color: var(--held-ink);
}
.pill--deny {
  background: var(--refused);
  color: var(--refused-ink);
}

@media (max-width: 48rem) {
  .mock__table th:nth-child(3),
  .mock__table td:nth-child(3) {
    display: none;
  }
}

/* ---------- split panel ---------- */

.split {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  margin-top: clamp(2.5rem, 6vh, 4.5rem);
}

.split__half {
  padding: 2rem;
  border: 1px solid var(--hair);
  border-radius: var(--radius);
  background: var(--near);
}

/* The half you want carries the warm end of the gradient. */
.split__half--lit {
  border-color: color-mix(in srgb, var(--warm) 40%, transparent);
  background: linear-gradient(
    165deg,
    color-mix(in srgb, var(--warm) 9%, var(--raised)),
    var(--near) 72%
  );
}

.split__label {
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 1.25rem;
}

.split__half--lit .split__label {
  color: var(--warm);
}

.plain {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.875rem;
}

.plain li {
  position: relative;
  padding-left: 1.375rem;
  color: var(--muted);
  font-size: var(--t-small);
  line-height: 1.6;
}

.plain li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 1px;
  background: var(--faint);
}

.split__half--lit .plain li::before {
  background: var(--warm);
  width: 10px;
}

/* ---------- rail panel type ---------- */

.rail__title {
  margin-bottom: 1.25rem;
}

.rail__body + .rail__body {
  margin-top: 1rem;
}

.rail__body {
  max-width: 44rem;
}

/* ---------- note ---------- */

.note {
  margin: clamp(2rem, 5vh, 3rem) auto 0;
  max-width: 44rem;
  padding: 1.25rem 1.5rem;
  border-left: 2px solid var(--warm);
  background: color-mix(in srgb, var(--warm) 6%, transparent);
  color: var(--muted);
  font-size: var(--t-small);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.note .mono {
  color: var(--warm);
}

/* ---------- FAQ ---------- */

.faq {
  max-width: 48rem;
  margin: clamp(2.5rem, 6vh, 4.5rem) auto 0;
  border-top: 1px solid var(--hair);
}

.faq__item {
  border-bottom: 1px solid var(--hair);
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.375rem 0;
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.125rem);
  font-weight: 500;
  letter-spacing: var(--tracking-tight);
  cursor: pointer;
  list-style: none;
  transition: color var(--quick) var(--ease-cursor);
}

.faq__q::-webkit-details-marker {
  display: none;
}

.faq__q::after {
  content: "";
  flex: none;
  width: 10px;
  height: 10px;
  border-right: 1.5px solid var(--faint);
  border-bottom: 1.5px solid var(--faint);
  rotate: 45deg;
  transition:
    rotate var(--mid-dur) var(--ease),
    border-color var(--quick) var(--ease-cursor);
}

.faq__item[open] .faq__q {
  color: var(--warm);
}

.faq__item[open] .faq__q::after {
  rotate: 225deg;
  border-color: var(--warm);
}

.faq__a {
  padding: 0 0 1.5rem;
  color: var(--muted);
  font-size: var(--t-small);
  line-height: 1.7;
  max-width: 42rem;
}

.faq__a .mono {
  color: var(--cold);
}

/* ---------- closing ---------- */

.closing {
  position: relative;
  padding-block: clamp(6rem, 16vh, 12rem);
  isolation: isolate;
  overflow: hidden;
}

/* An echo of the hero orb, so the page closes the way it opened. */
.closing::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -70%;
  width: min(120vw, 70rem);
  aspect-ratio: 1;
  translate: -50% 0;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(
    circle at 50% 40%,
    color-mix(in srgb, var(--warm) 65%, transparent) 0%,
    color-mix(in srgb, var(--mid) 45%, transparent) 40%,
    transparent 68%
  );
  filter: blur(34px);
  opacity: 0.42;
  pointer-events: none;
}

/* ---------- footer ---------- */

.foot {
  border-top: 1px solid var(--hair);
  padding-block: 3rem 4rem;
}

.foot__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem 2.5rem;
}

.foot__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
}

.foot__nav a {
  font-size: var(--t-small);
  color: var(--muted);
  text-decoration: none;
  transition: color var(--quick) var(--ease-cursor);
}

.foot__nav a:hover {
  color: var(--warm);
}

.foot__note {
  margin-inline-start: auto;
  font-size: var(--t-micro);
  color: var(--faint);
}

@media (max-width: 60rem) {
  .foot__note {
    margin-inline-start: 0;
  }
}

/* ---------------------------------------------------------------
   Code and terminal.

   The most persuasive picture a developer tool can show is its own
   output. Both of these are hand-marked rather than highlighted by a
   library: the sample is fixed, so shipping a parser to colour eleven
   lines would be weight for nothing.
   --------------------------------------------------------------- */

.showcase {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
  margin-top: clamp(2.5rem, 6vh, 4.5rem);
  align-items: start;
}

.pane {
  border: 1px solid var(--hair);
  border-radius: var(--radius);
  background: var(--near);
  overflow: hidden;
}

.pane__bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6875rem 1rem;
  border-bottom: 1px solid var(--hair);
  background: var(--raised);
}

.pane__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--hair-lit);
}

.pane__name {
  margin-inline-start: 0.625rem;
  font-family: var(--mono);
  font-size: var(--t-micro);
  color: var(--faint);
}

.pane__body {
  margin: 0;
  padding: 1.25rem;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 0.8125rem;
  line-height: 1.75;
  color: var(--muted);
  tab-size: 2;
}

.pane__body code {
  font-family: inherit;
}

/* Syntax. Kept to five roles — more colours than that stops being
   information and starts being noise. */
.tok-key {
  color: var(--mid);
}
.tok-fn {
  color: var(--cool);
}
.tok-str {
  color: var(--cold);
}
.tok-num {
  color: var(--warm);
}
.tok-com {
  color: var(--faint);
  font-style: italic;
}

/* Terminal output states, matching the pills elsewhere. A sage that
   belongs to the same warm family as --ran rather than the cyan-green a
   terminal usually reaches for, and the person's own amber for the one
   that means somebody is being waited on. */
.out-ok {
  color: #b5c9a0;
}
.out-hold {
  color: var(--person);
}
.out-model {
  color: var(--cold);
}
.out-dim {
  color: var(--faint);
}

/* The line the whole demo exists to produce. */
.pane__body mark {
  background: color-mix(in srgb, var(--warm) 16%, transparent);
  color: var(--paper);
  padding: 0.0625rem 0.25rem;
  border-radius: 3px;
}

/* ---------------------------------------------------------------
   The flow diagram.

   An action's path through the fence, drawn rather than described. The
   stroke animates on entry where the browser supports it.
   --------------------------------------------------------------- */

.flow {
  margin-top: clamp(2.5rem, 6vh, 4.5rem);
  padding: clamp(1.75rem, 4vw, 3rem);
  border: 1px solid var(--hair);
  border-radius: var(--radius);
  background: var(--near);
}

.flow svg {
  width: 100%;
  height: auto;
  overflow: visible;
}

.flow__node {
  fill: var(--raised);
  stroke: var(--hair-lit);
  stroke-width: 1;
}

.flow__node--warm {
  stroke: color-mix(in srgb, var(--warm) 60%, transparent);
}

.flow__node--cold {
  stroke: color-mix(in srgb, var(--cold) 60%, transparent);
}

.flow__label {
  fill: var(--paper);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.flow__sub {
  fill: var(--faint);
  font-family: var(--sans);
  font-size: 11px;
}

.flow__line {
  stroke: var(--hair-lit);
  stroke-width: 1;
  fill: none;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  /* Drawn on entry. pathLength="1" on the element makes the dash
     arithmetic independent of the path's real length. */
  animation: flow-draw 1.4s var(--ease) forwards;
}

.flow__line--warm {
  stroke: color-mix(in srgb, var(--warm) 70%, transparent);
}

.flow__line--cold {
  stroke: color-mix(in srgb, var(--cold) 70%, transparent);
}

@keyframes flow-draw {
  to {
    stroke-dashoffset: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .flow__line {
    animation: none;
    stroke-dashoffset: 0;
  }
}

@media (max-width: 48rem) {
  .flow {
    overflow-x: auto;
  }
  .flow svg {
    min-width: 34rem;
  }
}

/* ---------------------------------------------------------------
   The fence.

   The last thing on the page, and the only interactive picture on it.
   The canvas is a backdrop the closing headline stands in front of, so
   it takes no pointer events and carries no meaning a screen reader
   needs — fence.js draws the argument the copy above it already makes.
   --------------------------------------------------------------- */

.closing--fence {
  /* Short of a full viewport on purpose: the section plus the footer
     under it has to fit on one screen, or scrolling to the very bottom
     — which is what people do — clips the headline off the top and
     leaves the fence with nothing to be the closing image of. */
  min-height: 84svh;
  /* Ranged from the top rather than centred. Centring inside a section
     with a bottom padding this large pushes the headline up under the
     masthead, which is where the first attempt put it. */
  padding-block: clamp(5.5rem, 13vh, 8.5rem) clamp(11rem, 26vh, 18rem);
}

.fence {
  position: absolute;
  inset: auto 0 0;
  z-index: 0;
  width: 100%;
  /* Tall enough that the strokes have somewhere to grow from, short
     enough that the headline is never inside the field. */
  height: min(52%, 26rem);
  pointer-events: none;
}

/* The closing orb sits behind the fence rather than over it, so the
   strokes read as standing in front of a light rather than floating in
   a haze. It is pulled down and dimmed to make room. */
.closing--fence::before {
  bottom: -76%;
  opacity: 0.34;
}

.closing--fence .wrap {
  position: relative;
  z-index: 1;
}

/* A line of type under the fence, naming what it is. Without it the
   picture is decoration; with it, it is the last sentence of the
   argument. */
.fence__note {
  margin-top: clamp(1.75rem, 4vh, 2.5rem);
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* Reads over the top of the fence, so it needs more ink than the
     --faint the other small print gets. */
  color: var(--muted);
}

@media (max-width: 48rem) {
  .closing--fence {
    min-height: auto;
    padding-block: clamp(4rem, 10vh, 7rem) clamp(12rem, 30vh, 18rem);
  }

  .fence {
    height: min(52%, 18rem);
  }
}

/* ---------------------------------------------------------------
   The rail's demonstrations.

   Each layer's panel used to be two paragraphs and nothing else, which
   left the widest column on the page carrying only prose. Every panel
   now ends in the thing it is describing actually refusing something.
   --------------------------------------------------------------- */

.rail__pane {
  margin-top: clamp(1.5rem, 3vh, 2rem);
}

/* The tab column is 14rem of sticky nav and then nothing for the height
   of a panel. One line of type is enough to stop it reading as a
   mistake. */
.rail__aside {
  margin-top: 1.5rem;
  padding-left: 1.25rem;
  font-size: var(--t-micro);
  line-height: 1.6;
  color: var(--faint);
}

@media (max-width: 60rem) {
  .rail__aside {
    display: none;
  }
}

/* ---------------------------------------------------------------
   The authority bands.

   Three stacked zones: what you refused, what you opened to a model,
   and what you kept for a person. The middle one is the only place a
   model has any say, and the only place injected text can reach — which
   is the section's whole argument and was previously only words.

   Hairline seams, like .bento and .entries: the band boundaries are the
   point, so they are the only rules on it.
   --------------------------------------------------------------- */

.bands {
  display: grid;
  gap: 1px;
  margin-top: clamp(2.5rem, 6vh, 4.5rem);
  border: 1px solid var(--hair);
  border-radius: var(--radius);
  background: var(--hair);
  overflow: hidden;
}

.band {
  position: relative;
  padding: clamp(1.5rem, 3.5vw, 2.25rem) clamp(1.5rem, 3.5vw, 2.25rem)
    clamp(1.5rem, 3.5vw, 2.25rem) clamp(2rem, 4vw, 2.75rem);
  background: var(--near);
}

/* The band's own colour, carried on one property so the bar, the verbs
   and the label cannot disagree about which zone this is. */
.band::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--zone, var(--hair-lit));
}

/* Deliberately colourless — neither a person nor a model decided this
   one, a rule did. But --faint at 3px is invisible against --near, so
   the top band read as having no bar at all. */
.band--deny {
  --zone: var(--muted);
}

.band--model {
  --zone: var(--machine);
  background: linear-gradient(
    100deg,
    color-mix(in srgb, var(--cold) 7%, var(--near)),
    var(--near) 70%
  );
}

.band--person {
  --zone: var(--person);
  background: linear-gradient(
    100deg,
    color-mix(in srgb, var(--warm) 7%, var(--near)),
    var(--near) 70%
  );
}

.band__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  margin-bottom: 0.625rem;
}

.band__label {
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.1875rem);
  font-weight: 500;
  letter-spacing: var(--tracking-tight);
  color: var(--paper);
}

.band__verbs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}

.band__verbs span {
  padding: 0.1875rem 0.5625rem;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--zone) 45%, transparent);
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.06em;
  color: var(--zone);
  white-space: nowrap;
}

.band__who {
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--zone);
  margin-bottom: 0.75rem;
}

.band__note {
  color: var(--muted);
  font-size: var(--t-small);
  line-height: 1.65;
  max-width: 52ch;
}

/* The one line that says why the middle band matters. */
.band__reach {
  margin-top: 1rem;
  padding-top: 0.875rem;
  border-top: 1px dashed color-mix(in srgb, var(--zone) 35%, transparent);
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--zone);
}

/* ---------------------------------------------------------------
   The terminal replay.

   Every line is in the markup. While the script is playing, the ones it
   has not reached yet are hidden; when it finishes, or if it never runs
   at all, they are simply visible — so no-JS and reduced-motion get the
   finished transcript rather than an empty pane.
   --------------------------------------------------------------- */

.pane__body .tl {
  display: block;
  min-height: 1.75em;
}

[data-replaying] .tl:not([data-shown]) {
  visibility: hidden;
}

/* The caret sits after the last line the replay has reached — the last
   shown line that is not followed by another shown one. Decorative, so
   a browser without :has() simply gets no caret. */
[data-replaying] .tl[data-shown]:not(:has(+ .tl[data-shown]))::after {
  content: "▍";
  color: var(--warm);
  animation: caret 1s steps(2) infinite;
}

@keyframes caret {
  50% {
    opacity: 0;
  }
}

/* Waiting on a person: the whole pane breathes while nothing happens,
   which is the one moment in the demo where nothing happening is the
   thing being demonstrated. */
[data-held] {
  animation: held-breathe 1.6s ease-in-out infinite;
}

@keyframes held-breathe {
  50% {
    background: color-mix(in srgb, var(--held) 5%, transparent);
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-replaying] .tl:not([data-shown]) {
    visibility: visible;
  }
  [data-held] {
    animation: none;
  }
}

/* ---------------------------------------------------------------
   The diagram's traveller.
   --------------------------------------------------------------- */

.flow__dot {
  fill: var(--paper);
  filter: drop-shadow(0 0 6px var(--warm));
  transition: opacity var(--quick) var(--ease-cursor);
}

/* A node the action has reached. */
.flow__node.is-lit {
  stroke: var(--paper);
  fill: var(--lifted);
  transition:
    stroke var(--mid-dur) var(--ease),
    fill var(--mid-dur) var(--ease);
}

.flow__node--warm.is-lit {
  stroke: var(--warm);
}

.flow__node--cold.is-lit {
  stroke: var(--cold);
}

/* ---------------------------------------------------------------
   The budget meters.

   Same starting figure on both sides, same retry loop. One empties;
   the other never spends anything, because the first call is already
   over the per-action limit and the fence answers before the money
   moves.
   --------------------------------------------------------------- */

.burn {
  margin-top: 1.75rem;
  padding-top: 1.375rem;
  border-top: 1px solid var(--hair);
}

.burn__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.625rem;
}

.burn__label {
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}

.burn__figure {
  font-family: var(--mono);
  font-size: 1.0625rem;
  letter-spacing: -0.02em;
  color: var(--burn, var(--paper));
  font-variant-numeric: tabular-nums;
}

.burn__track {
  height: 4px;
  border-radius: 2px;
  background: var(--lifted);
  overflow: hidden;
}

.burn__fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--burn, var(--muted));
  transition: width 180ms linear;
}

.burn__state {
  margin-top: 0.625rem;
  font-family: var(--mono);
  font-size: var(--t-micro);
  color: var(--faint);
}

/* Draining is grey and going out, because nobody decided anything — it
   simply ran out. --refused is a pill ground meant to carry dark ink,
   and on this field it came out brighter than the fenced meter beside
   it, which put the emphasis on exactly the wrong half. Held is the
   person's warm, because a person is what it is waiting for. */
[data-burn-state-name="spent"] {
  --burn: var(--muted);
}

[data-burn-state-name="held"] {
  --burn: var(--warm);
}

[data-burn-state-name="held"] .burn__state {
  color: color-mix(in srgb, var(--warm) 75%, var(--muted));
}

/* ---------------------------------------------------------------
   Cards lean toward the pointer.

   --tx/--ty come from cursor.js, in the range -1..1 from the middle of
   the card. Four degrees: enough that the page has a surface, not
   enough to make anyone chase a moving target.
   --------------------------------------------------------------- */

.card,
.bento__cell {
  transform: perspective(800px) rotateX(calc(var(--ty, 0) * -4deg))
    rotateY(calc(var(--tx, 0) * 4deg));
  transition: transform var(--mid-dur) var(--ease-cursor);
}

@media (prefers-reduced-motion: reduce) {
  .card,
  .bento__cell {
    transform: none;
  }
}

/* ---------------------------------------------------------------
   The showcase, as a story rather than a row.

   Two panes stacked on the left — the code, then what it printed — and
   the phone standing beside them, because the order the reader needs is
   ask, wait, and then this is what a person actually gets.
   --------------------------------------------------------------- */

.showcase {
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
}

.showcase__panes {
  display: grid;
  gap: 1rem;
  min-width: 0;
}

@media (max-width: 62rem) {
  .showcase {
    grid-template-columns: 1fr;
  }
}

/* ---------------------------------------------------------------
   The approval mail, on a phone.

   The only light object on the page, and deliberately so: everything
   else here is the machine's side of the fence, and this is the human's.
   It is also the only picture of a physical thing, which is what the
   page was missing between one dark rounded rectangle and the next.

   The wording is the real mail's, down to the sentence about the link
   being single use.
   --------------------------------------------------------------- */

.phone {
  position: sticky;
  top: 7rem;
  margin: 0;
  justify-self: center;
  width: min(100%, 19.5rem);
  padding: 0.5rem;
  border-radius: 2.25rem;
  /* A bezel, lit from the top left the way the rest of the page is. */
  background: linear-gradient(160deg, var(--hair-lit), var(--near) 55%);
  box-shadow:
    0 2px 0 0 color-mix(in srgb, var(--paper) 8%, transparent) inset,
    0 40px 90px -30px rgb(0 0 0 / 0.85),
    0 0 0 1px var(--hair);
  rotate: -1.6deg;
  transition: rotate var(--slow) var(--ease), translate var(--slow) var(--ease);
}

/* Straightens when you go to read it. */
.phone:hover {
  rotate: 0deg;
  translate: 0 -4px;
}

.phone__screen {
  border-radius: 1.85rem;
  overflow: hidden;
  background: #f4f5f7;
  color: #1b1f27;
}

.phone__status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.6875rem 1.125rem 0.5rem;
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 600;
  color: #1b1f27;
}

.phone__dots {
  display: flex;
  gap: 3px;
}

.phone__dots i {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: #1b1f27;
}

.phone__cap {
  margin-top: 1.125rem;
  text-align: center;
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--faint);
  rotate: 1.6deg;
}

/* ---- the mail itself ---- */

.mail {
  padding: 0.875rem 1.125rem 1.375rem;
  font-size: 0.8125rem;
  line-height: 1.55;
}

.mail__from {
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #48505e;
}

.mail__subject {
  margin-top: 0.1875rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: #1b1f27;
}

.mail__body {
  margin-top: 0.875rem;
  padding-top: 0.875rem;
  border-top: 1px solid #d7dbe1;
}

.mail__eyebrow {
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #48505e;
}

.mail__amount {
  margin-top: 0.25rem;
  font-size: 1.75rem;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1;
  color: #1b1f27;
}

.mail__to {
  margin-top: 0.1875rem;
  color: #48505e;
}

/* The rule that stopped it, in the mail's own amber. */
.mail__reason {
  margin-top: 0.875rem;
  padding: 0.5rem 0.625rem;
  border-left: 3px solid #b3701c;
  background: #fbf3e7;
  font-family: var(--mono);
  font-size: 0.6875rem;
  color: #4d3204;
}

.mail__cta {
  margin-top: 0.875rem;
  padding: 0.625rem 1rem;
  border-radius: 8px;
  background: #3f6a4c;
  color: #fff;
  font-weight: 600;
  text-align: center;
}

.mail__fine {
  margin-top: 0.75rem;
  font-size: 0.6875rem;
  line-height: 1.5;
  color: #48505e;
}

@media (max-width: 62rem) {
  .phone {
    position: static;
    rotate: 0deg;
  }
  .phone__cap {
    rotate: 0deg;
  }
}

@media (prefers-reduced-motion: reduce) {
  .phone {
    rotate: 0deg;
    transition: none;
  }
  .phone:hover {
    translate: none;
  }
  .phone__cap {
    rotate: 0deg;
  }
}

/* ---------------------------------------------------------------
   Breaking the page's one rhythm.

   Every section was: centred pill, centred two-line headline with a
   gradient phrase, centred lede, row of rounded boxes. Six times over.
   No single one of those is wrong and all six together is the reason
   the page read as generated — there was one shape and the page never
   left it.

   What follows is the variation: heads that range left across two
   columns, sections that sit on their own ground, a numeral behind the
   head, and one moment with no box in it at all.
   --------------------------------------------------------------- */

/* ---- a head that ranges left, headline against lede ---- */

.section-head--split {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: end;
  text-align: left;
  max-width: none;
}

.section-head--split .eyebrow {
  grid-column: 1;
  justify-self: start;
  margin-bottom: 1.25rem;
}

.section-head--split .h1,
.section-head--split .h2 {
  grid-column: 1;
  grid-row: 2;
  max-width: 16ch;
}

.section-head--split .lede {
  grid-column: 2;
  grid-row: 2;
  /* Sits on the headline's baseline rather than under it, which is what
     makes this read as a spread and not as a stack that lost its
     centring. */
  padding-bottom: 0.375rem;
}

@media (max-width: 60rem) {
  .section-head--split {
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }
  .section-head--split .h1,
  .section-head--split .h2,
  .section-head--split .lede {
    grid-column: 1;
    grid-row: auto;
    max-width: none;
  }
}

/* ---- a section on its own ground ----
   Full bleed, so the band is the width of the window and the page reads
   as a stack of grounds rather than as one unbroken field. */

.section--raised {
  background: var(--near);
  border-block: 1px solid var(--hair);
}

/* ---- the numeral behind the head ----
   Set in the gradient at a size no text on the page reaches, clipped to
   its own glyphs and left at low opacity. It is a position marker, not
   a heading — hence aria-hidden on the attribute that draws it. */

.section[data-num] {
  position: relative;
}

.section[data-num]::before {
  content: attr(data-num);
  position: absolute;
  top: clamp(1rem, 3vh, 3rem);
  right: var(--gutter);
  z-index: 0;
  font-family: var(--mono);
  font-size: clamp(5rem, 12vw, 11rem);
  font-weight: 500;
  line-height: 0.8;
  letter-spacing: -0.06em;
  background-image: var(--sweep);
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  opacity: 0.09;
  pointer-events: none;
}

.section[data-num] > .wrap {
  position: relative;
  z-index: 1;
}

@media (max-width: 48rem) {
  .section[data-num]::before {
    opacity: 0.06;
  }
}

/* ---- the statement ----
   One line, no container, at a size nothing else on the page uses. The
   page needed somewhere it stops presenting and just says the thing.
   --------------------------------------------------------------- */

.statement {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(5rem, 14vh, 10rem);
  border-block: 1px solid var(--hair);
  background: var(--near);
}

/* A wash rising from the floor, so the type sits in light rather than
   on a slab. */
.statement::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -85%;
  width: min(130vw, 76rem);
  aspect-ratio: 1;
  translate: -50% 0;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(
    circle at 50% 40%,
    color-mix(in srgb, var(--mid) 55%, transparent),
    color-mix(in srgb, var(--cool) 30%, transparent) 45%,
    transparent 68%
  );
  filter: blur(60px);
  opacity: 0.3;
  pointer-events: none;
}

.statement__line {
  font-size: clamp(1.875rem, 1rem + 3.6vw, 4rem);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: var(--tracking-display);
  text-wrap: balance;
  max-width: 22ch;
}

.statement__by {
  margin-top: clamp(1.75rem, 4vh, 2.5rem);
  padding-top: 1.25rem;
  border-top: 1px solid var(--hair);
  max-width: 34rem;
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--faint);
}

/* ---- grain over everything ----
   The page is a lot of large flat fields and wide gradients, and an
   8-bit panel bands both. The hero and the fence each carried their own
   grain; this is the same texture over the whole document so the
   sections between them are not the only smooth ones.
   --------------------------------------------------------------- */

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  opacity: 0.035;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* The masthead already sits at 50 and the cursor at 9999, both above
   the grain. Nothing else needs raising: the layer takes no pointer
   events, so everything under it is still clickable. */

/* ---------------------------------------------------------------
   The approval page, playable.

   Sits under the phone, because the phone shows the mail and this is
   the page its link opens. Pressing either button writes the trail that
   choice produces — and the point of it is what Deny writes, which is
   nothing downstream at all.
   --------------------------------------------------------------- */

.decide {
  grid-column: 1 / -1;
  margin-top: clamp(1.5rem, 4vh, 2.5rem);
  border: 1px solid var(--hair);
  border-radius: var(--radius);
  background: var(--near);
  overflow: hidden;
  transition: border-color var(--mid-dur) var(--ease);
}

.decide[data-decided="approve"] {
  border-color: color-mix(in srgb, var(--person) 45%, transparent);
}

.decide[data-decided="deny"] {
  border-color: var(--hair-lit);
}

.decide__bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6875rem 1rem;
  border-bottom: 1px solid var(--hair);
  background: var(--raised);
}

.decide__body {
  padding: clamp(1.5rem, 4vw, 2.25rem);
}

.decide__eyebrow {
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}

/* The verb, at the size the decision deserves. It is the one word that
   decides whether this is safe. */
.decide__verb {
  margin-top: 0.375rem;
  font-family: var(--mono);
  font-size: clamp(1.75rem, 1.2rem + 2vw, 2.75rem);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--person);
}

.decide__host {
  margin-top: 0.375rem;
  font-family: var(--mono);
  font-size: var(--t-small);
  color: var(--paper);
}

.decide__path {
  margin-top: 0.25rem;
  font-family: var(--mono);
  font-size: var(--t-micro);
  color: var(--faint);
  word-break: break-all;
}

.decide__rule {
  margin-top: 1.25rem;
  padding: 0.75rem 1rem;
  border-left: 2px solid var(--person);
  background: color-mix(in srgb, var(--person) 7%, transparent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: var(--t-small);
  color: var(--muted);
  max-width: 52ch;
}

.decide__act {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

.decide__act[hidden] {
  display: none;
}

.decide__yes {
  background: var(--person);
  color: var(--black);
}

.decide__no:hover {
  border-color: var(--hair-lit);
  background: color-mix(in srgb, var(--paper) 6%, transparent);
}

.decide__fine {
  margin-top: 1rem;
  font-size: var(--t-micro);
  color: var(--faint);
  max-width: 52ch;
}

/* ---- the trail this choice wrote ---- */

.decide__trail:not(:empty) {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--hair);
}

.decide__row {
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.875rem;
  font-family: var(--mono);
  font-size: var(--t-micro);
  line-height: 1.9;
  color: var(--muted);
}

.decide__t {
  color: var(--faint);
  flex: none;
}

.decide__e {
  min-width: 11rem;
  flex: none;
}

.decide__d {
  color: var(--faint);
}

.decide__row[data-tone="ok"] .decide__e {
  color: #b5c9a0;
}

.decide__row[data-tone="dim"] .decide__d {
  font-style: italic;
}

/* The line the whole thing exists to produce, either way. */
.decide__row[data-tone="mark"] .decide__e {
  background: color-mix(in srgb, var(--person) 18%, transparent);
  color: var(--paper);
  padding: 0.0625rem 0.375rem;
  border-radius: 3px;
}

.decide__sum {
  margin-top: 1rem;
  font-size: var(--t-small);
  color: var(--paper);
  max-width: 52ch;
}

.decide__again {
  margin-top: 1.25rem;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--faint);
  cursor: pointer;
  border-bottom: 1px solid var(--hair-lit);
  transition: color var(--quick) var(--ease-cursor);
}

.decide__again:hover {
  color: var(--person);
}

.decide__again[hidden] {
  display: none;
}

/* ---------------------------------------------------------------
   The count before the page.

   Two halves meeting at a rule. The count runs on the top half; the
   rule between them fills as it climbs; and at 100 they part and the
   page is behind the gap.

   That is not a generic wipe picked because it looked nice. It is the
   only thing this product does — a fence with one gap in it, and you go
   through the gap. The fence at the foot of the page is the same idea
   drawn a different way.

   The page beneath is complete and readable the whole time, which is
   why the overlay is aria-hidden and why leaving is a parting rather
   than a fade. Nothing is revealed; it was always there.
   --------------------------------------------------------------- */

.loader {
  position: fixed;
  inset: 0;
  z-index: 9998;
  display: flex;
  flex-direction: column;
  pointer-events: none;
}

/* Held until the script decides. Without this the panel flashes on a
   fast connection and on every back-navigation. */
html:not(.is-loading) .loader {
  display: none;
}

/* The page does not scroll under a panel nobody can see past. */
html.is-loading,
html.is-loading body {
  overflow: hidden;
}

.loader__half {
  flex: 1;
  background: var(--black);
  display: flex;
  /* Each half moves on its own transform, so the two springs in
     loader.js have one property each and nothing to fight. */
  will-change: transform;
}

.loader__half--top {
  align-items: flex-end;
  padding: var(--gutter);
}

.loader__inner {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  width: 100%;
}

.loader__mark {
  display: flex;
  flex-direction: column;
  line-height: 0.95;
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: -0.03em;
  color: var(--paper);
}

.loader__mark span:last-child {
  color: var(--person);
}

/* The count, at a size nothing else on the site reaches. Tabular, so
   the digits do not shuffle as it climbs. */
.loader__num {
  font-family: var(--mono);
  font-size: clamp(4rem, 3rem + 9vw, 11rem);
  font-weight: 500;
  line-height: 0.8;
  letter-spacing: -0.06em;
  color: var(--paper);
  font-variant-numeric: tabular-nums;
}

/* The seam. It fills as the count climbs, and it is the line the two
   halves part along. */
.loader__rule {
  position: relative;
  flex: none;
  height: 2px;
  background: var(--hair);
  overflow: hidden;
  will-change: opacity;
}

.loader__bar {
  display: block;
  height: 100%;
  background: var(--person);
  transform: scaleX(0);
  transform-origin: 0 50%;
}

@media (prefers-reduced-motion: reduce) {
  .loader {
    display: none;
  }
}
