/* ==========================================================================
   Yummy Systems — Theme
   --------------------------------------------------------------------------
   Visual language: a candy-swirl lollipop set on brushed stainless steel,
   its wordmark on a strip of hand-cut blue painter's tape. Sweet product,
   serious kitchen — the warmth belongs to the brand, the steel to the room.

   Two accents, and they don't trade jobs:
     --tape   blue, the interface  — links, buttons, focus, active states
     --candy  red, the brand       — the logo, and very little else

   Requires the IBM Plex superfamily. Load it in the document <head>:

     <link rel="preconnect" href="https://fonts.googleapis.com">
     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
     <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@500&family=IBM+Plex+Sans+Condensed:wght@600;700&family=IBM+Plex+Sans:wght@400;500&display=swap" rel="stylesheet">

   Contents
     1. Tokens
     2. Dark mode
     3. Reset & base
     4. Typography
     5. Layout
     6. Components
     7. Motion
     8. Utilities
   ========================================================================== */


/* 1. Tokens ============================================================== */

:root {
  /* -- Surface: brushed stainless -------------------------------------- */
  --steel-hi:    #EDEFF0;   /* raking highlight, top of the sheet          */
  --steel-mid:   #D8DDDF;   /* body of the sheet                          */
  --steel-lo:    #E4E8E9;   /* return light, bottom                       */

  /* Grain flecks that make the steel read as brushed, not flat */
  --grain-hi:    rgba(255, 255, 255, 0.5);
  --grain-lo:    rgba(20, 24, 26, 0.035);

  /* -- Ink -------------------------------------------------------------- */
  --ink:         #14181A;   /* Sharpie black                              */
  --ink-soft:    #4A5257;   /* secondary copy, captions                   */

  /* -- Accent: blue painter's tape --------------------------------------
     The *interface* accent. Links, focus rings, buttons, active states.
     ---------------------------------------------------------------------- */
  --tape:        #2C7FBE;
  --tape-edge:   #1F6099;   /* the shadowed lower edge of a taped strip   */
  --tape-ink:    #F4F8FB;   /* text written on tape                       */

  /* -- Brand: the lollipop ----------------------------------------------
     The *brand* accent, and the only warm colour in the system. It belongs
     to the logo. Don't spend it on buttons or links — blue does that job,
     and the candy stops being special the moment it's everywhere.
     ---------------------------------------------------------------------- */
  --candy:       #E8384F;   /* the swirl                                  */
  --candy-deep:  #B4283C;   /* the rim that defines the pop's edge        */
  --candy-cream: #FFF6EC;   /* the sugar between the stripes              */
  --candy-stick: #E7DCCB;   /* paper stick                                */

  /* -- Flag --------------------------------------------------------------
     The one interface job the warm accent is allowed to take: something
     went wrong and the reader has to see it. Aliased rather than used
     directly so error states never reach for --candy by name.
     ---------------------------------------------------------------------- */
  --flag:        var(--candy-deep);

  /* -- Panels & lines ---------------------------------------------------- */
  --panel:       rgba(255, 255, 255, 0.44);
  --panel-edge:  rgba(255, 255, 255, 0.6);
  --rule:        rgba(20, 24, 26, 0.14);

  --shadow-1:    0 3px 10px rgba(20, 24, 26, 0.22);
  --shadow-2:    0 12px 34px rgba(20, 24, 26, 0.14);

  /* -- Screen ------------------------------------------------------------
     The display over the pass. A dark hardware bezel, and the violet the
     artwork throws onto the counter under it. --screen-glow is sampled from
     the artwork itself, which is the only reason a third hue is allowed in
     the system: it is light, not paint. Nothing else may use it.
     ---------------------------------------------------------------------- */
  --screen-case-hi: #23282B;   /* top of the moulded bezel                 */
  --screen-case-lo: #0E1113;   /* its shadowed lower half                  */
  --screen-glow:    rgba(124, 90, 168, 0.42);
  --screen-bezel:   clamp(0.5rem, 1.4vw, 0.9rem);
  --screen-h:       min(50svh, 30rem);   /* caps the frame so the copy under
                                            it still clears a laptop fold  */

  /* -- Fruit --------------------------------------------------------------
     The one full palette in the system, and the reason it is allowed: these
     are pictures of fruit. A blue strawberry is not a stylistic choice, it
     is a mistake. Fenced the way --screen-* is fenced — only a fruit mark
     may touch these. Interface colour is still --tape; brand is still
     --candy.

     Deliberately *not* redefined for dark mode, on the same logic that keeps
     the screen bezel dark in both: a lemon is yellow in a dark room too.
     ---------------------------------------------------------------------- */
  --fruit-berry:  #E8384F;   /* strawberry                                 */
  --fruit-lemon:  #EFC04A;
  --fruit-orange: #EC8A3C;
  --fruit-pear:   #86B24A;
  --fruit-melon:  #EE6377;   /* watermelon flesh                           */
  --fruit-rind:   #4E9153;   /* and its rind                               */
  --fruit-kiwi:   #B7D46A;
  --fruit-skin:   #8B6B45;   /* kiwi skin                                  */
  --fruit-leaf:   #5FA05A;
  --fruit-stem:   #7A6A52;
  --fruit-seed:   #3C4A2E;
  --fruit-pith:   #FFF6EC;   /* seeds, pith, the shine on a peel           */

  /* -- The steel field itself, as one reusable value --------------------- */
  --steel-field:
    repeating-linear-gradient(90deg, var(--grain-hi) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, var(--grain-lo) 0 1px, transparent 1px 2px),
    linear-gradient(160deg, var(--steel-hi) 0%, var(--steel-mid) 55%, var(--steel-lo) 100%);

  /* -- Type ------------------------------------------------------------- */
  --font-display: "IBM Plex Sans Condensed", "IBM Plex Sans", sans-serif;
  --font-body:    "IBM Plex Sans", system-ui, -apple-system, sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;

  --size-display-xl: clamp(2.75rem, 1.5rem + 6.2vw, 6.5rem);
  --size-display-l:  clamp(2rem, 1.35rem + 3.2vw, 3.75rem);
  --size-display-m:  clamp(1.5rem, 1.2rem + 1.5vw, 2.25rem);
  --size-body:       clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
  --size-mono:       clamp(0.9rem, 0.85rem + 0.2vw, 1rem);
  --size-label:      clamp(0.75rem, 0.7rem + 0.2vw, 0.875rem);
  --size-meta:       0.6875rem;

  --track-display: -0.022em;  /* tight, so condensed caps lock together   */
  --track-label:    0.22em;   /* wide, like stencilled equipment labels   */
  --track-meta:     0.16em;

  /* -- Space ------------------------------------------------------------ */
  --space-1: 0.5rem;
  --space-2: 0.75rem;
  --space-3: 1.1rem;
  --space-4: clamp(1.5rem, 3.5vw, 2.25rem);
  --space-5: clamp(1.75rem, 4vw, 2.75rem);
  --space-6: clamp(3rem, 8vh, 5rem);
  --gutter:  clamp(1.5rem, 5vw, 4rem);

  --measure:  46rem;   /* page shell                                      */
  --measure-wide: 60rem; /* shell for a view led by a full-width image    */
  --measure-copy: 34ch; /* comfortable reading width for body copy        */
  --measure-prose: 62ch; /* longer line, for documents read top to bottom */

  /* -- Motion ----------------------------------------------------------- */
  --ease-settle: cubic-bezier(0.2, 0.8, 0.25, 1);
  --ease-nudge:  cubic-bezier(0.2, 0.7, 0.3, 1);
  --dur-fast:    160ms;
  --dur-mid:     620ms;
  --dur-slow:    700ms;
}


/* 2. Dark mode ===========================================================
   Same sheet of steel, lit from a colder angle — gunmetal, not black.

   Applied two ways, and the two blocks below must be kept in sync:
     - by system preference, unless the page forces light
     - by <html data-theme="dark">, which wins over the system preference
   Set data-theme="light" to force light mode on a dark-mode system.
   ======================================================================== */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --steel-hi:   #1E2325;
    --steel-mid:  #14181A;
    --steel-lo:   #191E20;

    --grain-hi:   rgba(255, 255, 255, 0.045);
    --grain-lo:   rgba(0, 0, 0, 0.16);

    --ink:        #E8EDEF;
    --ink-soft:   #98A3A8;

    --tape:       #2A76B0;
    --tape-edge:  #17557F;
    --tape-ink:   #EEF5FA;

    /* Candy stays candy — brightened just enough to hold up on gunmetal. */
    --candy:       #F0566B;
    --candy-deep:  #C2304A;
    --candy-cream: #FFF6EC;
    --candy-stick: #D9CDB8;

    /* The deep rim goes muddy on gunmetal; the swirl itself carries. */
    --flag:        var(--candy);

    --panel:      rgba(255, 255, 255, 0.045);
    --panel-edge: rgba(255, 255, 255, 0.09);
    --rule:       rgba(232, 237, 239, 0.16);

    --shadow-1:   0 3px 10px rgba(0, 0, 0, 0.5);
    --shadow-2:   0 12px 34px rgba(0, 0, 0, 0.45);

    /* A lit screen carries further in a dark room. */
    --screen-case-hi: #2A3033;
    --screen-case-lo: #0B0E0F;
    --screen-glow:    rgba(139, 102, 189, 0.6);
  }
}

:root[data-theme="dark"] {
  --steel-hi:   #1E2325;
  --steel-mid:  #14181A;
  --steel-lo:   #191E20;

  --grain-hi:   rgba(255, 255, 255, 0.045);
  --grain-lo:   rgba(0, 0, 0, 0.16);

  --ink:        #E8EDEF;
  --ink-soft:   #98A3A8;

  --tape:       #2A76B0;
  --tape-edge:  #17557F;
  --tape-ink:   #EEF5FA;

  /* Candy stays candy — brightened just enough to hold up on gunmetal. */
  --candy:       #F0566B;
  --candy-deep:  #C2304A;
  --candy-cream: #FFF6EC;
  --candy-stick: #D9CDB8;

  /* The deep rim goes muddy on gunmetal; the swirl itself carries. */
  --flag:        var(--candy);

  --panel:      rgba(255, 255, 255, 0.045);
  --panel-edge: rgba(255, 255, 255, 0.09);
  --rule:       rgba(232, 237, 239, 0.16);

  --shadow-1:   0 3px 10px rgba(0, 0, 0, 0.5);
  --shadow-2:   0 12px 34px rgba(0, 0, 0, 0.45);

  /* A lit screen carries further in a dark room. */
  --screen-case-hi: #2A3033;
  --screen-case-lo: #0B0E0F;
  --screen-glow:    rgba(139, 102, 189, 0.6);
}

/* Tell form controls and scrollbars which mode they're in. */
:root { color-scheme: light dark; }
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }


/* 3. Reset & base ======================================================== */

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  min-height: 100svh;
  padding: var(--gutter);

  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--size-body);
  line-height: 1.6;

  background-color: var(--steel-mid);
  background-image: var(--steel-field);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
}

img, svg, video { max-width: 100%; height: auto; }

:focus-visible {
  outline: 2px solid var(--tape);
  outline-offset: 4px;
  border-radius: 1px;
}


/* 4. Typography ========================================================== */

h1, h2, h3, .display-xl, .display-l, .display-m {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 0.95;
  letter-spacing: var(--track-display);
  text-wrap: balance;
}

h1, .display-xl { font-size: var(--size-display-xl); }
h2, .display-l  { font-size: var(--size-display-l); }
h3, .display-m  { font-size: var(--size-display-m); line-height: 1.1; }

/* Lede — the one sentence under a headline. */
.lede {
  margin: var(--space-4) 0 0;
  max-width: var(--measure-copy);
  color: var(--ink-soft);
}

/* Eyebrow — a stencilled label above a heading. Not on tape. */
.eyebrow {
  margin: 0 0 var(--space-2);
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--size-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Meta — the smallest utility text: footers, timestamps, statuses. */
.meta {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--size-meta);
  letter-spacing: var(--track-meta);
  text-transform: uppercase;
  color: var(--ink-soft);
}


/* 5. Layout ============================================================== */

/* .page — full-height frame: content centered, footer pinned to the bottom. */
.page {
  display: grid;
  grid-template-rows: 1fr auto;
  min-height: calc(100svh - (var(--gutter) * 2));
}

/* .shell — the measure everything aligns to. */
.shell {
  width: 100%;
  max-width: var(--measure);
  margin-inline: auto;
}

/* .shell--wide — for a view that needs to lay things out side by side: a
   card grid, a table. Copy inside it still takes its own measure. */
.shell--wide { max-width: var(--measure-wide); }

/* .shell--screen — a shell for a view led by a .screen. It takes the frame's
   own width, so the picture and the copy under it share one left edge instead
   of the frame floating centred inside a wider column. */
.shell--screen { max-width: min(var(--measure-wide), calc(var(--screen-h) * 16 / 9)); }

/* .stack — vertical rhythm for a run of blocks. */
.stack { display: flex; flex-direction: column; }
.stack > * + * { margin-top: var(--space-4); }

.center-y {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Centred content that outgrows the viewport overflows in *both* directions,
   and the top half becomes unreachable — no scrollbar goes that way. Safe
   centring falls back to flex-start the moment that would happen. Declared
   separately: a browser that doesn't know the keyword drops the whole rule. */
@supports (justify-content: safe center) {
  .center-y { justify-content: safe center; }
}


/* 6. Components ========================================================== */

/* -- Logo ---------------------------------------------------------------
   The lollipop mark, leaning the way a pop leans when you set it down.
   .lockup pairs it with the wordmark on tape: candy taped to the counter.
   ---------------------------------------------------------------------- */
.lockup {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* .tape pins itself to flex-start for column layouts; centre it in a lockup. */
.lockup > .tape { align-self: center; }

.logo-mark {
  flex: none;
  width: auto;
  height: clamp(2.75rem, 6.5vw, 4rem);
}

.logo-mark--sm { height: 2.25rem; }

/* The lollipop leans the way a pop leans when you set it down. Upright marks
   (the YS monogram) don't take this. */
.logo-mark--lean {
  transform: rotate(7deg);
  transform-origin: bottom center;
}

a.lockup { text-decoration: none; }

/* -- Tape ---------------------------------------------------------------
   The signature. A strip of blue painter's tape torn off the roll and
   pressed onto the steel: uneven ends, translucent weave, lifted edge.
   Use it once per view — it stops being an artifact if it repeats.
   ---------------------------------------------------------------------- */
.tape {
  display: inline-block;
  align-self: flex-start;
  margin: 0;
  padding: 0.7rem 1.6rem 0.75rem;

  background-color: var(--tape);
  background-image: repeating-linear-gradient(
    92deg,
    rgba(255, 255, 255, 0.07) 0 2px,
    rgba(0, 0, 0, 0.05) 2px 4px
  );
  border-top: 1px solid rgba(255, 255, 255, 0.22);
  border-bottom: 1px solid var(--tape-edge);
  box-shadow: var(--shadow-1);

  /* uneven ends, the way tape tears off the roll */
  clip-path: polygon(0.7% 0, 100% 2.5%, 99.2% 100%, 0 96%);
  transform: rotate(-1.4deg);
  transform-origin: left center;

  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--size-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--tape-ink);
  text-decoration: none;
}

/* Torn the other way — alternate so repeat uses don't look stamped. */
.tape--right { transform: rotate(1.1deg); transform-origin: right center; }
.tape--flat  { transform: none; }

a.tape:hover,
a.tape:focus-visible { color: #fff; }

/* -- Mono link ----------------------------------------------------------
   Underlined in tape blue, with an arrow that steps forward on hover.
   ---------------------------------------------------------------------- */
.link-mono {
  display: inline-flex;
  align-items: baseline;
  gap: 0.6rem;
  padding-bottom: 0.2rem;

  color: var(--ink);
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--size-mono);
  text-decoration: none;
  border-bottom: 2px solid var(--tape);
  transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease;
}

.link-mono .arrow { transition: transform 220ms var(--ease-nudge); }

.link-mono:hover,
.link-mono:focus-visible { color: var(--tape); }

.link-mono:hover .arrow,
.link-mono:focus-visible .arrow { transform: translateX(0.35rem); }

/* -- Button -------------------------------------------------------------
   Equipment-panel switch: square, labelled, no gloss.
   ---------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.5rem;
  border: 1px solid transparent;
  border-radius: 2px;
  cursor: pointer;

  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--size-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  text-decoration: none;
  transition: background-color var(--dur-fast) ease,
              border-color var(--dur-fast) ease,
              color var(--dur-fast) ease;
}

.btn--primary {
  background-color: var(--tape);
  border-color: var(--tape-edge);
  color: var(--tape-ink);
}
.btn--primary:hover,
.btn--primary:focus-visible { background-color: var(--tape-edge); }

.btn--ghost {
  background-color: transparent;
  border-color: var(--rule);
  color: var(--ink);
}
.btn--ghost:hover,
.btn--ghost:focus-visible { border-color: var(--tape); color: var(--tape); }

/* -- Panel --------------------------------------------------------------
   A lighter plate set on the steel field. For grouped content on
   interior pages.
   ---------------------------------------------------------------------- */
.panel {
  padding: clamp(1.25rem, 3vw, 2rem);
  background-color: var(--panel);
  border: 1px solid var(--panel-edge);
  border-radius: 3px;
  box-shadow: var(--shadow-2);
  backdrop-filter: blur(6px);
}

/* -- Card grid ----------------------------------------------------------
   A row of small plates on the counter — capabilities, services, the four
   marks. Wraps to two-up and then one-up on its own; no breakpoints needed.
   Pair with .panel for the plate itself.

     <div class="card-grid">
       <div class="panel"><p class="eyebrow">Label</p><p>One line.</p></div>
     </div>
   ---------------------------------------------------------------------- */
.card-grid {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}

/* Column counts for a set of a known size. Left to itself, auto-fit packs in
   as many 13rem columns as will fit and strands the remainder on a short last
   row — four cards become 3 + 1, six become 4 + 2. Raising the floor caps the
   count without a breakpoint: the min() keeps the floor honest, collapsing to
   a single column once the column is narrower than the floor itself.

     --2   a set of four, two-up      (18rem floor: 3 columns can't fit)
     --3   a set of six, three-up     (17rem floor: 4 columns can't fit)  */
.card-grid--2 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}

.card-grid--3 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}

.card-grid > .panel > :last-child { margin-bottom: 0; }

/* -- Fruit ---------------------------------------------------------------
   The one place the system carries a full palette, and the reason it is
   allowed: these are pictures of fruit, and a blue strawberry is not a
   stylistic choice, it is a mistake. Treated the way --screen-glow is
   treated — a carve-out with a fence around it. Nothing but a fruit mark
   may use these; interface colour is still --tape, brand is still --candy.
   ---------------------------------------------------------------------- */
.card-icon {
  display: block;
  width: auto;
  height: 2.5rem;
  margin-bottom: var(--space-2);
}

/* -- Notice -------------------------------------------------------------
   A short status message: something was sent, or something needs fixing.
   A plate on the steel with a painted stripe down its leading edge.

     <p class="notice">Message sent.</p>
     <p class="notice notice--flag">Something needs fixing.</p>
   ---------------------------------------------------------------------- */
.notice {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  max-width: var(--measure-prose);

  background-color: var(--panel);
  border: 1px solid var(--panel-edge);
  border-left: 3px solid var(--tape);
  border-radius: 2px;
}

.notice--flag { border-left-color: var(--flag); }

.notice > :first-child { margin-top: 0; }
.notice > :last-child  { margin-bottom: 0; }

/* -- Form ---------------------------------------------------------------
   Fields are let into the counter rather than set on top of it: a shallow
   well, a dark inner lip, and the tape blue only when the field is live.
   Labels are stencilled like everything else that names a piece of
   equipment.

     <form class="form">
       <p class="field">
         <label class="label" for="name">Name</label>
         <input class="input" id="name" name="name" type="text">
       </p>
     </form>
   ---------------------------------------------------------------------- */
.form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: 34rem;
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0;
}

.label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--size-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* The asterisk is decoration — the word "required" is what gets announced. */
.label .req { color: var(--tape); }

.input,
.textarea {
  width: 100%;
  padding: 0.7rem 0.85rem;

  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--size-body);
  line-height: 1.5;

  background-color: var(--panel);
  border: 1px solid var(--rule);
  border-radius: 2px;
  box-shadow: inset 0 1px 2px rgba(20, 24, 26, 0.09);
  transition: border-color var(--dur-fast) ease, box-shadow var(--dur-fast) ease;
}

.textarea {
  min-height: 9rem;
  resize: vertical;
}

.input::placeholder,
.textarea::placeholder { color: var(--ink-soft); opacity: 0.75; }

/* The default focus ring is an outline offset *outside* the box, which reads
   as a halo around a field rather than the field switching on. Swap it for a
   ring drawn tight to the border — same colour, same job, no gap. */
.input:focus,
.textarea:focus {
  outline: none;
  border-color: var(--tape);
  box-shadow: inset 0 1px 2px rgba(20, 24, 26, 0.09),
              0 0 0 3px rgba(44, 127, 190, 0.24);
}

/* Set by the server on a field that came back wrong, alongside the message
   in .field-note — never colour alone. */
.input[aria-invalid="true"],
.textarea[aria-invalid="true"] { border-color: var(--flag); }

.field-note {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--ink-soft);
}

.field-note--flag { color: var(--flag); }

/* -- Prose --------------------------------------------------------------
   Long-form document copy: policies, terms, notices — pages that are read
   top to bottom rather than scanned. .lede runs at --measure-copy because
   it is one sentence under a headline; a document needs a longer line than
   that, so .prose carries its own measure and its own vertical rhythm.

   Section headings step down to --size-display-m. Inside a document a
   heading is a signpost, not a headline, and an h2 at display-l would
   shout over the title of the page it sits under.

     <div class="prose">
       <h2>Section</h2>
       <p>…</p>
     </div>

   Bullets are a short stroke of tape rather than a disc — the same mark
   that gets drawn on a container lid, at the size a list can carry it.
   ---------------------------------------------------------------------- */
.prose { max-width: var(--measure-prose); }

.prose > * { margin-top: var(--space-3); margin-bottom: 0; }
.prose > :first-child { margin-top: 0; }

.prose h2 {
  margin-top: var(--space-5);
  font-size: var(--size-display-m);
  line-height: 1.1;
}

.prose h3 {
  margin-top: var(--space-4);
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--size-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Plex Sans is loaded at 400 and 500 only — 700 here would be synthesised. */
.prose strong { font-weight: 500; }

/* Inline links. .prose applies this to every anchor inside it; use .link
   directly for a link in a lede, a caption, or anywhere else in running copy
   — a bare <a> has no house style and falls back to browser blue. */
.link,
.prose a {
  color: var(--tape);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease;
}

.link:hover,
.link:focus-visible,
.prose a:hover,
.prose a:focus-visible { color: var(--ink); border-bottom-color: var(--tape); }

.prose ul { padding-left: 0; list-style: none; }
.prose li { position: relative; padding-left: 1.5rem; }
.prose li + li { margin-top: var(--space-1); }

.prose li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.68em;
  width: 0.6rem;
  height: 2px;
  background-color: var(--tape);
}

.prose hr {
  margin-top: var(--space-5);
  height: 1px;
  border: 0;
  background-color: var(--rule);
}

/* -- Screen -------------------------------------------------------------
   The display over the pass. Artwork that arrives with its own palette does
   not get blended into the steel — it gets a hardware bezel, a shadow, and
   the light it throws onto the counter beneath it. Framed that way it reads
   as something switched on in the room, so its colours are the picture's
   business rather than a second brand fighting the first.

   --screen-h caps the height, and the 16:9 max-width is derived from it, so
   the frame gives ground on short viewports instead of pushing the copy off
   the fold. Set --screen-h locally for other ratios.

   Like .tape, one per view.

     <figure class="screen">
       <img src="…" alt="…" width="1280" height="720">
       <p class="tape screen__tab">In prep</p>
     </figure>
   ---------------------------------------------------------------------- */
.screen {
  position: relative;
  width: 100%;
  max-width: calc(var(--screen-h) * 16 / 9);
  margin: 0 auto;
  padding: var(--screen-bezel);
  border-radius: 5px;

  background-image: linear-gradient(168deg, var(--screen-case-hi), var(--screen-case-lo));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.16),   /* moulding, catching the light */
    0 0 0 1px rgba(0, 0, 0, 0.4),              /* the seam of the case         */
    var(--shadow-2),
    0 26px 64px -20px var(--screen-glow);      /* what it spills on the steel  */
}

.screen > img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 2px;

  /* The artwork's own background, so the glass is already dark on a slow
     connection and the frame doesn't flash white before the file paints. */
  background-color: #14192C;
}

/* A strip torn off and stuck across the case, half on it and half on the
   steel — the one thing tying the picture to the room it sits in. Runs
   tighter than a standalone .tape: it labels the object, it isn't the
   headline. The overlap is measured down from the frame's bottom edge, so it
   stays a constant sliver of case at every frame size rather than eating a
   tenth of the picture on a phone. Offset with margin, never a transform —
   .anim-tape needs the transform to itself. */
.screen__tab {
  position: absolute;
  left: clamp(1rem, 6%, 3rem);
  top: 100%;
  margin-top: calc((var(--screen-bezel) + 0.3rem) * -1);
  z-index: 1;
  padding: 0.5rem 1.15rem 0.55rem;
}

/* -- Actions ------------------------------------------------------------
   A row of links or buttons closing out a block of copy.
   ---------------------------------------------------------------------- */
.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
  margin: var(--space-5) 0 0;
}

/* -- Rule ---------------------------------------------------------------- */
.rule {
  height: 1px;
  margin: 0;
  border: 0;
  background-color: var(--rule);
}

/* -- Site header --------------------------------------------------------- */
.site-header {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-4);
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-5);
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--size-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.site-nav a {
  color: var(--ink-soft);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
  transition: color var(--dur-fast) ease, border-color var(--dur-fast) ease;
}

.site-nav a:hover,
.site-nav a:focus-visible,
.site-nav a[aria-current="page"] {
  color: var(--ink);
  border-bottom-color: var(--tape);
}

/* -- Site footer --------------------------------------------------------- */
.site-footer {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  justify-content: space-between;

  margin-top: var(--space-6);
  padding-top: var(--space-3);
  border-top: 1px solid var(--rule);

  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--size-meta);
  letter-spacing: var(--track-meta);
  text-transform: uppercase;
  color: var(--ink-soft);
}

.site-footer a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--rule); }
.site-footer a:hover,
.site-footer a:focus-visible { color: var(--ink); border-bottom-color: var(--tape); }


/* 7. Motion ==============================================================
   One orchestrated load-in: the tape settles, then the headline rises.
   Opt in per element with .anim-*; stagger with .delay-*.
   ======================================================================== */

@keyframes tape-settle {
  from { opacity: 0; transform: translateY(-14px) rotate(-5.5deg); }
  to   { opacity: 1; transform: translateY(0) rotate(-1.4deg); }
}

@keyframes rise {
  from { opacity: 0; transform: translateY(100%); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes fade-up {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* The screen comes on: the panel lifts into place as the backlight catches. */
@keyframes screen-wake {
  from { opacity: 0; transform: translateY(10px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* The pop is set down on the counter: drops in and rocks to rest. */
@keyframes pop-set-down {
  0%   { opacity: 0; transform: translateY(-18px) rotate(-12deg) scale(0.82); }
  60%  { opacity: 1; transform: translateY(0) rotate(11deg) scale(1); }
  100% { opacity: 1; transform: translateY(0) rotate(7deg) scale(1); }
}

/* .rise clips its child so the line appears to slide out from behind a mask.
   Put .rise on the wrapper and .anim-rise on the child it clips. */
.rise { display: block; overflow: hidden; }
.rise > * { display: block; }

@media (prefers-reduced-motion: no-preference) {
  .anim-pop    { animation: pop-set-down 760ms var(--ease-settle) both; }
  .anim-screen { animation: screen-wake 820ms var(--ease-settle) both; }
  .anim-tape { animation: tape-settle var(--dur-mid) var(--ease-settle) both; }
  .anim-rise { animation: rise var(--dur-slow) var(--ease-settle) both; }
  .anim-up   { animation: fade-up var(--dur-slow) ease-out both; }

  /* An even ladder, so a page can cascade top to bottom without doing maths. */
  .delay-1 { animation-delay: 160ms; }
  .delay-2 { animation-delay: 280ms; }
  .delay-3 { animation-delay: 400ms; }
  .delay-4 { animation-delay: 520ms; }
  .delay-5 { animation-delay: 640ms; }
  .delay-6 { animation-delay: 760ms; }
}


/* 8. Utilities =========================================================== */

.measure-copy { max-width: var(--measure-copy); }
.ink-soft     { color: var(--ink-soft); }
.mt-4 { margin-top: var(--space-4); }
.mt-5 { margin-top: var(--space-5); }
.mb-5 { margin-bottom: var(--space-5); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
