/* Sibling. One stylesheet, hand authored, CUBE order:
   0 normalize, 1 tokens, 2 composition, 3 utilities, 4 blocks, 5 exceptions.
   Built against runs/phase2/web/token_plan.md; nothing here is invented at the
   keyboard. No gradient, no shadow, no radius but 0 and 999px, and no
   hand-cursor declaration anywhere: that property's value carries a substring
   the banned-family grep in docs/ANTI_SLOP.md section 2.1 fails on, and every
   control here is a real button, anchor or input that carries the platform
   cursor without being told. Formatting is compact on purpose; the same house
   style as the approved round-3 artboards. */

/* ---- 0. modern-normalize 3.0.1, MIT, Sindre Sorhus. Three rules are dropped
   rather than copied. The document face is set from --body in section 4
   instead, because upstream's stack carries two banned family names.
   `code,kbd,samp,pre` declared a fourth font-family stack for elements no
   template here contains. `b,strong` set font-weight:bolder, which would
   synthesise bold on Plex Arabic, which ships at 400 only, and that is what
   tests/test_web_fonts.py exists to prevent. Nothing else is edited. ---- */
*,::before,::after{box-sizing:border-box}
html{line-height:1.15;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4}
body{margin:0}
hr{height:0;color:inherit}
abbr[title]{text-decoration:underline dotted}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sub{inset-block-end:-0.25em}
sup{inset-block-start:-0.5em}
table{text-indent:0;border-color:inherit}
button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}
button,select{text-transform:none}
button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}
::-moz-focus-inner{border-style:none;padding:0}
:-moz-focusring{outline:1px dotted ButtonText}
legend{padding:0}
progress{vertical-align:baseline}
::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}
[type=search]{-webkit-appearance:textfield;outline-offset:-2px}
::-webkit-search-decoration{-webkit-appearance:none}
::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}
summary{display:list-item}

/* ---- 1. Tokens ---- */

/* Registered so the accent animates as a colour rather than as a string,
   which is what motion 2 in section 5 needs. */
@property --accent{syntax:"<color>";inherits:true;initial-value:oklch(0.470 0.095 172)}
@property --accent-ring{syntax:"<color>";inherits:true;initial-value:oklch(0.470 0.095 172)}

/* 1.1 light literals. Hue 150 is a cool grey-green board stock, fixed by
   PLAN.md 6.1 as deliberately not cream. Every neutral carries chroma; there
   is no pure black and no pure white in this file. The two accent values and
   the wash hue are written onto the root element by the server, per result. */
:root{
  --wash-h:150;
  --paper:oklch(0.955 0.009 150);
  --ink:oklch(0.235 0.014 150);
  --paper-2:oklch(0.922 0.010 150);
  --rule:oklch(0.845 0.010 150);
  --ink-2:oklch(0.505 0.012 150);
  --accent-l:oklch(0.470 0.095 172);
  --accent-d:oklch(0.780 0.085 172);
  --ring-l:oklch(0.470 0.095 172);
  --ring-d:oklch(0.780 0.085 172);
  --display:"Bricolage Grotesque","Sleeve Display Fallback","IBM Plex Sans Arabic",sans-serif;
  --body:"IBM Plex Sans Arabic","Sleeve Body Fallback",sans-serif;
  --mono:"Commit Mono","Sleeve Mono Fallback",monospace;
  --t-11:11px;--t-14:14px;--t-17:17px;--t-21:21px;--t-27:27px;
  --t-display:clamp(33px,9vw,52px);
  --s-1:4px;--s-2:8px;--s-3:12px;--s-4:16px;--s-5:24px;--s-6:40px;--s-7:64px;--s-8:96px;
  --spine-w:28px;--gutter:24px;
  /* The fallbacks are verdigris, PLAN.md 6.1, and are what an ungraded page
     paints. Same two colours as app/web/render.py FALLBACK_INK_*. */
  --accent:var(--accent-l,oklch(0.470 0.095 172));
  --accent-ring:var(--ring-l,oklch(0.470 0.095 172));
  color-scheme:light dark;
}

/* 1.2 dark literals. A repaint, not a filter: separate values, no inversion
   and no dimming of the page. */
@media (prefers-color-scheme:dark){
  :root{
    --paper:oklch(0.178 0.012 150);
    --ink:oklch(0.935 0.008 150);
    --paper-2:oklch(0.225 0.012 150);
    --rule:oklch(0.320 0.012 150);
    --ink-2:oklch(0.700 0.010 150);
    --accent:var(--accent-d,oklch(0.780 0.085 172));
    --accent-ring:var(--ring-d,oklch(0.780 0.085 172));
  }
}

/* 1.3 and 1.4 the ink wash: light branch then dark branch, both inside one
   @supports so the dark branch is always the last thing to assign these three
   tokens in either mode. Source order decides this cascade, not specificity,
   so the order of these four blocks is load bearing and
   tests/test_web_ink_wash.py asserts it by byte offset. Lightness and chroma
   come from the literal on the same line, so the wash provably cannot move
   either one; --wash-h defaults to 150, so a page carrying no accent hue, and
   a browser with no relative colour syntax, both render the unwashed ramp. */
@supports (color:oklch(from red l c h)){
  :root{
    --paper-2:oklch(from oklch(0.922 0.010 150) l c var(--wash-h));
    --rule:oklch(from oklch(0.845 0.010 150) l c var(--wash-h));
    --ink-2:oklch(from oklch(0.505 0.012 150) l c var(--wash-h));
  }
  @media (prefers-color-scheme:dark){
    :root{
      --paper-2:oklch(from oklch(0.225 0.012 150) l c var(--wash-h));
      --rule:oklch(from oklch(0.320 0.012 150) l c var(--wash-h));
      --ink-2:oklch(from oklch(0.700 0.010 150) l c var(--wash-h));
    }
  }
}

/* 1.5 the three faces, self hosted. Nothing here asks Google Fonts or Typekit
   for anything, and every src resolves under /static/fonts/. */
@font-face{font-family:"Bricolage Grotesque";src:url(/static/fonts/bricolage-grotesque-latin.woff2) format("woff2");font-weight:300 800;font-style:normal;font-display:swap}
@font-face{font-family:"IBM Plex Sans Arabic";src:url(/static/fonts/ibm-plex-sans-arabic.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
/* The same file a second time, restricted to the Arabic blocks the subset
   carries, declared last so an Arabic codepoint matches it rather than falling
   through the display stack into Bricolage. */
@font-face{font-family:"IBM Plex Sans Arabic";src:url(/static/fonts/ibm-plex-sans-arabic.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap;unicode-range:U+0600-06FF,U+0750-077F,U+08A0-08FF,U+200C-200F}
@font-face{font-family:"Commit Mono";src:url(/static/fonts/commit-mono-latin.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}

/* 1.6 metric matched shims, local sources only, so they download nothing and
   the swap costs no layout shift. Measured against the real faces on this
   machine; where neither local face exists the stack falls through to the
   generic, which is the behaviour it would have with no shim at all. */
@font-face{font-family:"Sleeve Display Fallback";src:local("Arial"),local("Helvetica");size-adjust:92.8%;ascent-override:100.2%;descent-override:29.1%;line-gap-override:0%;unicode-range:U+0000-024F,U+2000-206F}
@font-face{font-family:"Sleeve Body Fallback";src:local("Arial"),local("Helvetica");size-adjust:98.5%;ascent-override:110.2%;descent-override:42.1%;line-gap-override:0%}
@font-face{font-family:"Sleeve Mono Fallback";src:local("Courier New");size-adjust:100%;ascent-override:90%;descent-override:20%;line-gap-override:0%}

/* ---- 2. Composition: two tracks, and nothing centred ---- */

body{background:var(--paper);color:var(--ink);font-family:var(--body);
  font-size:var(--t-17);line-height:1.55;-webkit-font-smoothing:antialiased;
  overflow-wrap:break-word}

/* The screen is a flex row: the spine column, then the page. Under dir="rtl"
   the row reverses and the spine moves to the other edge without one physical
   offset being written. */
.screen{display:flex;position:relative;min-height:100svh;background:var(--paper)}
.page{flex:1 1 auto;position:relative;min-width:0}

/* Body content is inset from the cover's own edge, and the cover is flush to
   the inline-end edge, so no screen is a centred stack. */
.txt{padding-inline-end:var(--gutter)}

.skip{position:absolute;inset-block-start:0;inset-inline-start:0;
  display:flex;align-items:center;min-block-size:48px;
  padding:var(--s-2) var(--s-3);background:var(--paper-2);color:var(--ink);
  transform:translateY(-200%)}
.skip:focus{transform:none}

/* ---- 3. Utilities ---- */
.quiet{color:var(--ink-2)}
.measure{max-width:62ch}
.gap-4{margin-block-start:var(--s-4)}
.gap-5{margin-block-start:var(--s-5)}
.gap-8{margin-block-start:var(--s-8)}
.away{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

/* ---- 4. Blocks ---- */
h1,h2,p,ul,ol,dl,dd,figure{margin:0}
ul,ol{padding:0;list-style:none}
button,input{font:inherit;color:inherit;background:none;border:0;margin:0;
  padding:0;border-radius:0;-webkit-appearance:none;appearance:none;text-align:inherit}
a{color:inherit;text-decoration:none}
img{max-width:100%;border-radius:0}
a:focus-visible,button:focus-visible,input:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

/* 4.1 the printed spine, the one signature move. 28 px, full height, mono,
   painted in the extracted ink, reading bottom to top, pinned to the column
   block-start so the catalogue number is inside the first 390 by 844 and stays
   there while the page scrolls, the way a spine stays readable on a shelf. */
.spine{flex:0 0 var(--spine-w);position:relative}
.spine-blank{flex:0 0 var(--spine-w)}
/* The pin sits on a horizontally written wrapper. inset-block-start resolves
   against the element's own writing mode, so on the vertical span it used to
   mean right:0 and pinned nothing on a page that never scrolls sideways. */
.spine-p{position:sticky;top:0;display:block;writing-mode:horizontal-tb}
.spine-t{display:block;
  writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--mono);
  font-size:var(--t-11);line-height:var(--spine-w);letter-spacing:0.09em;
  word-spacing:var(--s-3);color:var(--accent);white-space:nowrap;
  padding-inline-end:var(--s-5)}

/* 4.2 the cover. The whole square is the play target; the ring is the cue. */
.coverbox{position:relative;width:100%;aspect-ratio:1/1;background:var(--paper-2)}
.coverbtn{display:block;position:relative;width:100%;height:100%;padding:0;border:0;background:none}
/* The outline used to be drawn at offset -3px, inside the content box, where
   the replaced image paints over it: focused and unfocused screenshots were
   pixel identical. The ring is painted by an overlay after the image instead,
   so it lands on top, and a positive offset is not used because the button is
   flush to the viewport edge and would clip. */
.coverbtn:focus-visible{outline:0}
.coverbtn:focus-visible::after{content:"";position:absolute;inset:0;
  border:3px solid var(--ink);outline:2px solid var(--paper);outline-offset:-5px}
.cover{display:block;width:100%;height:100%;object-fit:cover;border-radius:0}

/* The ring is aria-hidden inside the button, is not focusable and carries no
   glyph: a control drawn inside a control is the accessory this page removed.
   Two paper keylines, one outside the stroke and one inside it, carry the
   boundary on a cover corner that clears neither variant (ADR-0007 point 3). */
.ringwrap{position:absolute;inset-inline:0;inset-block-end:var(--s-4);display:flex;padding-inline:var(--s-4)}
.ring{position:relative;width:64px;height:64px;border-radius:999px;
  border:2px solid var(--accent-ring);outline:1px solid var(--paper)}
.ring::before{content:"";position:absolute;inset:0;border-radius:999px;border:1px solid var(--paper)}
/* An alternate drawn over a cover the ring was never graded against drops the
   accent stroke: that removes a placement rather than adding an ungraded one.
   The stroke becomes the page ink, not a third paper keyline, because paper on
   paper on paper is no boundary and this is the only play cue on the page. Ink
   between two paper keylines reads against any cover by construction. */
.ring.ungraded{border-color:var(--ink)}

/* The seed's sleeve in the far corner of the pick's, at the ring's own inset so
   the two sit on one optical line. Three paper edges frame it off the artwork;
   the fourth, facing into the cover, is the 2 px accent rule. Both the corner
   and the ruled edge are logical, so dir=rtl flips them together.

   Documented exception 2, runs/phase2/visual/NOTES.md: a fourth accent
   placement beside the three PLAN.md 6.1 fixes, 144 square pixels of one. */
.seedmark{position:absolute;inset-inline-end:var(--s-4);inset-block-end:var(--s-4);
  width:72px;height:72px;object-fit:cover;border-radius:0;
  background:var(--paper-2);border:3px solid var(--paper);
  border-inline-start:2px solid var(--accent)}
.seed-cap{font-family:var(--mono);font-size:var(--t-11);line-height:1.45;
  letter-spacing:0.01em;color:var(--ink-2);margin-block-start:var(--s-2);
  padding-inline-end:var(--gutter)}

/* While an embed failure is live the YouTube Music control is the way out, so
   it is the one loud thing in the row: PLAN 6.2 asks for the box to revert to
   the cover and promote it, and nothing used to change it at all. */
.act.promoted{border-color:var(--ink);border-width:2px;text-decoration:underline;text-underline-offset:3px}

/* Graft 3: while the player is live the ring is gone, not faded, and the spine
   drops to the quiet ink. Instant, no transition. */
.playing .ring{display:none}
/* The corner and its caption go with the ring: while a video is running the
   page is the video, and a still of a second record over it is the accessory
   taste gate 10 asks to be named and removed. */
.playing .seedmark,.playing .seed-cap{display:none}
.playing .spine-t{color:var(--ink-2)}
.player{position:absolute;inset:0;width:100%;height:100%;border:0}

/* 4.3 the pick */
.title{font-family:var(--display);font-size:var(--t-display);line-height:1.06;
  letter-spacing:-0.02em;font-weight:620;text-wrap:pretty}
.title.ar{font-family:var(--body);font-size:calc(0.94 * var(--t-display));
  line-height:1.35;letter-spacing:0;font-weight:400}
.byline{font-size:var(--t-17);line-height:1.3;color:var(--ink-2);margin-block-start:var(--s-2)}
.accent-rule{height:2px;width:96px;background:var(--accent);margin-block-start:var(--s-4)}
.weak{font-size:var(--t-14);line-height:1.5;color:var(--ink-2);margin-block-start:var(--s-4)}
.reason{font-size:var(--t-17);line-height:1.55;margin-block-start:var(--s-4);max-width:62ch}
.reason.ar{line-height:1.7}

/* 4.4 the credits block: label column, value column, one stored fact a line.
   This is a sleeve printing its credits, so it is the page's smallest and
   quietest type rather than its loudest. */
.credits{display:grid;grid-template-columns:4.5rem minmax(0,1fr);
  column-gap:var(--s-3);row-gap:var(--s-1);margin-block-start:var(--s-4);
  font-family:var(--mono);font-size:var(--t-11);line-height:1.45;
  letter-spacing:0.01em;color:var(--ink-2)}
.credits dt,.credits dd{text-align:start}
/* Each dd carries dir="ltr" so a hex or a rank resolves left to right, and
   `start` inside an LTR element is its left edge: under an Arabic page that
   left the value 88 px from its label at 390 and 350 px at 1440. `end` is the
   edge the label is on. A max-content column does not hold: one row is wider
   than the track, so the rest still hang off. */
[dir=rtl] .credits dd{text-align:end}
/* The deep link is its cell's whole content, so 2.5.8's inline exception does
   not reach it: border box 44 px, margin box the line height. WEB-M8. */
.credits a{display:inline-flex;align-items:center;min-block-size:44px;
  margin-block:calc((44px - 1.45em) / -2)}

/* 4.5 alternates: contact prints laid straight on the paper. No card, no
   border, no fill, no padding box, aligned to one hairline under the row. */
.alts-h{font-size:var(--t-14);line-height:1.4;margin-block-start:var(--s-6)}
.alts{display:flex;gap:var(--s-3);margin-block-start:var(--s-3);overflow-x:auto;
  padding-block-end:var(--s-3);border-block-end:1px solid var(--rule);
  touch-action:manipulation;scrollbar-width:thin}
.altcell{flex:0 0 auto;width:100px}
.alt{display:block;width:100%}
/* The per-alternate provenance link is the whole content of its own line, so
   ADR-0013 section 3's inline exemption does not reach it: it is a standalone
   control and takes the 44 px floor the credits deep link already takes, on
   both axes. `min-block-size` alone left the box 36.52 by 44 on both engines
   at all five widths, because the words are shorter than the floor: the
   inline floor is the other half and the label is centred inside it rather
   than pushed to one edge. `margin-block-start` is the 8 px clearance the same
   rule asks for, and it is positive: the comment here used to claim a negative
   block margin this rule has never contained. */
.alt-src{display:inline-flex;align-items:center;justify-content:center;
  min-block-size:44px;min-inline-size:44px;
  font-size:var(--t-11);line-height:1.35;color:var(--ink-2);
  margin-block-start:var(--s-2)}
.alt img,.alt-ph{display:block;width:100px;height:100px;object-fit:cover;border-radius:0;background:var(--paper-2)}
.alt-txt,.alt-t,.alt-b,.alt-c{display:block}
.alt-txt{min-width:0}
.alt-t{font-size:var(--t-14);line-height:1.25;margin-block-start:var(--s-2)}
/* The Latin alternate title takes the display face and the display tracking
   and not a heavier weight. Plex Arabic ships 400 only, so a Latin title at
   600 sat beside Arabic titles at 400 in the same row at the same size and
   read as a different colour of ink. Taste gate 6. */
.alt-t.lat{font-family:var(--display);letter-spacing:-0.01em}
.alt-b{font-size:var(--t-11);line-height:1.3;color:var(--ink-2);margin-block-start:var(--s-1)}
.alt-c{font-size:var(--t-11);line-height:1.35;color:var(--ink-2);margin-block-start:var(--s-2)}
.alts-f{font-size:var(--t-11);line-height:1.45;color:var(--ink-2);margin-block-start:var(--s-3)}
/* One credit per source that fired, built from result.attribution. A page
   that named a source which contributed nothing was stating a fact no
   result produced. */
.attr{font-size:var(--t-11);line-height:1.45;color:var(--ink-2);margin-block-start:var(--s-5)}
.attr li{display:block;margin-block-start:var(--s-2)}
/* Each credit is its own line and its link is that line's whole content, so
   ADR-0013 section 3's inline exemption does not reach it either: the 44 px
   floor applies and this is it, drawn the way `.credits a` is drawn so a
   44 px box costs the list no height. */
.attr a{display:inline-flex;align-items:center;min-block-size:44px;
  color:inherit;text-decoration:underline;text-underline-offset:3px}
.badge{display:inline-block;min-height:44px;line-height:44px}

/* 4.6 rating */
.rate{margin-block-start:var(--s-5)}
.rate-h{font-size:var(--t-14);line-height:1.4}
.rate-row,.chips{display:flex;gap:var(--s-2);margin-block-start:var(--s-3);flex-wrap:wrap}
/* Square, hairline, machine face. The full-round pill with a centred sans
   label was the one component on this page that would have survived being
   lifted into another product unchanged, which is taste gate 9. A rating is a
   thing the product records about itself, so it is set the way the rest of
   this page sets what it records: a square box on a hairline, in the mono. */
.pill{height:48px;min-width:96px;border:1px solid var(--rule);color:var(--ink);
  font-family:var(--mono);font-size:var(--t-14);letter-spacing:0.01em;
  display:grid;place-items:center;padding-inline:var(--s-5)}
.chip{height:48px;border:1px solid var(--rule);font-family:var(--mono);
  font-size:var(--t-14);letter-spacing:0.01em;
  display:grid;place-items:center;padding-inline:var(--s-4)}
.pill[aria-pressed=true],.chip[aria-pressed=true]{background:var(--paper-2)}

/* 4.7 the sticky action row: four controls pressed into a shifted strip.
   A shift or a hairline, never both on one edge, so there is no border here. */
.actions{position:sticky;inset-block-end:0;background:var(--paper-2);
  padding-block:var(--s-3) max(var(--s-3),env(safe-area-inset-bottom,0px));
  padding-inline:var(--s-4);display:flex;flex-wrap:wrap;gap:var(--s-2);
  margin-block-start:var(--s-8)}
/* `min-width:0` let a control shrink below its own words, and `.act` clips
   rather than overhanging, so at 320 px the primary escape hatch painted
   `YouTube Mus` and the Arabic `Not it` lost its first letter. The floor is
   the control's own content instead, and the row wraps when four of them no
   longer fit: two rows of 48 px targets is the honest answer at 320, and a
   clipped label is not one. Four controls still fit on one row from about
   400 px up, which is where they fitted before. */
.act{flex:1 1 auto;min-width:max-content;height:48px;background:var(--paper);
  color:var(--ink);font-size:var(--t-14);line-height:1;display:grid;
  place-items:center;padding-inline:var(--s-3);white-space:nowrap}
.act.wide{flex:1.6 1 auto}
.act[disabled]{color:var(--ink-2)}
/* The only outbound YouTube link. A standalone control, so it reaches 48 px
   on the block axis like every other one, and inline-flex rather than block so
   the target is the width of its words and not of the column. The rule under
   it is a text decoration and not the block-end border the footer links use,
   because a border on a 48 px box draws its hairline 24 px under the words and
   reads as a stray rule. At 11 px with no rule at all it read as body copy. */
.second{display:inline-flex;align-items:center;min-block-size:48px;
  font-size:var(--t-11);color:var(--ink-2);margin-block-start:var(--s-2);
  text-decoration:underline;text-decoration-color:var(--rule);
  text-decoration-thickness:1px;text-underline-offset:3px}
.notice{font-size:var(--t-14);line-height:1.5;margin-block-start:var(--s-4)}
.said{font-size:var(--t-14);line-height:1.5;margin-block-start:var(--s-3);color:var(--ink-2)}
.said a{border-block-end:1px solid var(--rule)}

/* 4.8 home */
.wordmark{font-family:var(--display);font-size:var(--t-27);line-height:1;font-weight:700;letter-spacing:0.01em}
/* On the error page and the failure log the wordmark is the way back, so it
   is a control at 48 px. On home it is an h1 with no anchor inside it. */
.wordmark a{display:inline-flex;align-items:center;min-block-size:48px}
.lede{font-size:var(--t-17);line-height:1.45;margin-block-start:var(--s-5);max-width:24ch}
/* 50 px of border box, because ADR-0013 section 3 extends the 48 px row floor
   to the Paste and submit keys and the box's own 1 px border was taking two
   of them off the controls inside it: both measured 46. The 8 px the same
   rule asks for between them is a gap inside the field rather than a second
   box, so the field is still one field with a key on its end. */
.field{display:flex;align-items:stretch;height:50px;gap:var(--s-2);
  margin-block-start:var(--s-7);border:1px solid var(--rule);border-radius:0}
.input{flex:1 1 auto;min-width:0;font-size:var(--t-17);letter-spacing:-0.015em;
  color:var(--ink);padding:var(--s-2) var(--s-3)}
.input::placeholder{color:var(--ink-2)}
.paste{flex:0 0 48px;background:var(--paper-2);font-size:var(--t-14);color:var(--ink);
  display:grid;place-items:center}
.submit{width:100%;margin-block-start:var(--s-2);height:48px;background:var(--ink);
  color:var(--paper);font-size:var(--t-17);display:grid;place-items:center}
.submit.off{background:var(--paper-2);color:var(--ink-2)}
.helper{font-size:var(--t-14);line-height:1.5;color:var(--ink-2);margin-block-start:var(--s-4)}
.ios{margin-block-start:var(--s-8);padding-block-start:var(--s-4);border-block-start:1px solid var(--rule)}
.ios-h{font-size:var(--t-14);line-height:1.4}
.ios-l{font-size:var(--t-14);line-height:1.5;color:var(--ink-2);margin-block-start:var(--s-2)}
.shortcut{display:grid;place-items:center;width:fit-content;height:48px;
  padding-inline:var(--s-5);margin-block-start:var(--s-4);background:var(--paper-2);
  color:var(--ink);font-size:var(--t-14)}
.foot{font-family:var(--mono);font-size:var(--t-11);line-height:1.5;color:var(--ink-2);
  margin-block-start:var(--s-6);padding-block-end:var(--s-6)}
.foot a,.err-p a,.log a{border-block-end:1px solid var(--rule)}

/* 4.9 resolving. The mark does not travel: it advances on a real backend event
   and is repainted with no transition, so it can never show a percentage and
   it only ever moves because something happened. */
.reserved{width:100%;aspect-ratio:1/1;background:var(--paper-2)}
.track{position:relative;height:1px;background:var(--rule);margin-block-start:var(--s-5)}
.track i{position:absolute;inset-block-start:0;inset-inline-start:0;width:96px;
  height:1px;background:var(--ink-2)}
.stages{margin-block-start:var(--s-5);display:flex;flex-direction:column;gap:var(--s-3)}
.stage{font-size:var(--t-14);line-height:1.5;color:var(--ink-2)}
.stage.now{font-size:var(--t-21);line-height:1.3;color:var(--ink)}
.asking{font-family:var(--mono);font-size:var(--t-11);line-height:1.45;
  letter-spacing:0.01em;color:var(--ink-2);margin-block-start:var(--s-5)}
.wait{width:100%;margin-block-start:var(--s-7)}

/* 4.9b the choice page: only the row is new, the type is all borrowed. */
.choice{display:flex;align-items:center;gap:var(--s-3);border-block-start:1px solid var(--rule)}
.choice img{flex:0 0 48px;height:48px;object-fit:cover}
.choice .alt-txt{flex:1}
.choice .alt-ph{flex:0 0 48px;height:48px}
.choice .alt-t,.choice .alt-b,.choice .log-m{margin-block-start:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* 4.10 errors and the public failure log */
.err-h{font-size:var(--t-21);line-height:1.3;margin-block-start:var(--s-7)}
.err-p{font-size:var(--t-17);line-height:1.55;margin-block-start:var(--s-3);max-width:62ch}
.err-a{display:inline-grid;place-items:center;height:48px;padding-inline:var(--s-5);
  margin-block-start:var(--s-5);background:var(--paper-2);font-size:var(--t-14)}
.log{margin-block-start:var(--s-5)}
.log li{padding-block:var(--s-3);border-block-start:1px solid var(--rule)}
.log-t{font-size:var(--t-17);line-height:1.3}
.log-m{font-family:var(--mono);font-size:var(--t-11);line-height:1.45;
  color:var(--ink-2);margin-block-start:var(--s-1)}

/* 4.11 an element the server or a module hid stays hidden. This sits at the end
   of the blocks because `.chips`, `.submit` and `.act` all set a display, and
   an author display beats the user agent's `[hidden]` rule whatever its
   specificity. Without this the rating chips, the Cancel control and the
   in-app notice all paint before anything has happened. */
[hidden]{display:none}

/* 4.12 Arabic never falls into the machine face. Commit Mono's subset is Latin
   and digits, so an Arabic footer set in it lands on whatever monospaced face
   the platform has, which is not a designed face and is not what PLAN.md 6.1
   asks for. The credits block is unaffected: it is Latin by construction. */
:lang(ar) .foot,:lang(ar) .seed-cap{font-family:var(--body);font-size:var(--t-14)}
/* The rating labels are Arabic words on the Arabic page, so they leave the
   mono for the same reason the footer does. The square box and the hairline
   are what carry the treatment and they are unaffected. */
:lang(ar) .pill,:lang(ar) .chip{font-family:var(--body);letter-spacing:normal}

/* 4.13 the eval panel, Phase 3. The only page in this product where a wildcard
   or a placebic reason ever renders. */
.eval{margin-block-start:var(--s-6)}
.eval-h{font-size:var(--t-21);line-height:1.3}
.eval-item{padding-block:var(--s-4);border-block-start:1px solid var(--rule)}
.eval-row{display:flex;gap:var(--s-2);margin-block-start:var(--s-3);flex-wrap:wrap}

/* ---- 5. Exceptions ---- */

/* 5.1 Motion. Three, and nothing else: two keyframe animations and one
   transition, all declared inside this guard, none over 220 ms, no overshoot,
   no loop, no blanket transition. */
@media (prefers-reduced-motion:no-preference){
  @keyframes cover-in{from{opacity:0}to{opacity:1}}
  @keyframes alt-in{from{opacity:0}to{opacity:1}}
  .cover{animation:cover-in 220ms linear both}
  /* Motion 2 needs a value to move from. A result arrives as a navigation, so
     both registered accent properties were already final on the first paint
     and this transition was declared, correct and never observed.
     @starting-style is the before state: the sheet lands on verdigris and
     walks to the cover's ink, on the result and on every Not it swap. Without
     @starting-style a browser paints the final ink at once, as it did. */
  :root{transition:--accent 200ms linear,--accent-ring 200ms linear}
  @starting-style{
    :root{--accent:oklch(0.470 0.095 172);--accent-ring:oklch(0.470 0.095 172)}
  }
  /* The dark sheet starts from the dark verdigris, so the walk is between two
     inks of the same lightness rather than a jump across the ramp. */
  @media (prefers-color-scheme:dark){
    @starting-style{
      :root{--accent:oklch(0.780 0.085 172);--accent-ring:oklch(0.780 0.085 172)}
    }
  }
  .altcell{animation:alt-in 180ms linear both}
  .altcell:nth-child(2){animation-delay:40ms}
  .altcell:nth-child(3){animation-delay:80ms}
  .altcell:nth-child(4){animation-delay:120ms}
}

/* 5.2 The one hover affordance, and the fourth accent placement, filed as
   documented exception 1 in the token plan. It lives inside a hover query so
   it does not exist on a phone, every control carries the 1 px slot in a
   transparent colour at rest so hovering shifts no layout, and it paints no
   pixel until a pointing device is over a control. */
@media (hover:hover){
  .act,.shortcut,.submit,.err-a{border-block-end:1px solid transparent}
  .act:hover,.shortcut:hover,.submit:hover,.err-a:hover{border-block-end-color:var(--accent)}
}

/* 5.3 Desktop, the secondary breakpoint. An asymmetric grid, cover column 52
   percent, type column 48, alternates as a vertical list, the action row
   still stuck to the bottom of the type column. The cover stays the largest
   element and nothing is centred. */
@media (min-width:900px){
  :root{--gutter:64px}
  .desk{display:grid;grid-template-columns:52fr 48fr;gap:var(--s-7);
    max-width:90rem;padding-inline-end:var(--s-7);align-items:start}
  .desk .txt{padding-inline-end:0}
  /* The caption is in the cover column, so it takes that column's edge. */
  .seed-cap{padding-inline-end:0}
  .desk-col{padding-block-start:var(--s-5)}
  .title{font-weight:640;letter-spacing:-0.025em}
  .alts{display:block;overflow-x:visible;border-block-end:0;padding-block-end:0}
  .altcell{width:auto}
  .alt{display:flex;gap:var(--s-4);width:auto;padding-block:var(--s-4);
    border-block-start:1px solid var(--rule)}
  .alt img{width:64px;height:64px;flex:0 0 auto}
  .alt-t{font-size:var(--t-17);margin-block-start:0}
  .alt-b{font-size:var(--t-14)}
  /* The row stays stuck above 900 px. Unstuck it was last in the type column
     and landed at or below the fold on all three results at 1440 by 900,
     while 256 px of empty paper sat under the cover column beside it: a
     desktop visitor saw a cover, a title and a reason with no visible way to
     play. Only the block margin changes at this breakpoint now. */
  .actions{margin-block-start:var(--s-6)}
  /* `.act.wide` outranks `.act`, so the phone's 1.6 grow factor survives this
     breakpoint unless it is reset here, and without the reset YouTube Music
     renders a 350 px slab beside three 80 px controls. The controls keep the
     phone's paper on the strip's paper-2, because the strip is still a strip
     up here; painting them paper-2 as well would put four invisible boxes on
     it. */
  .act,.act.wide{flex:0 0 auto;padding-inline:var(--s-5)}
}
