/* ledger - the auth flow's stylesheet, lifted from
   design/mocks/signin-house.html with the mock's own scaffolding chrome
   (.scaffold, .page, .manifest, .rules, .scr, .steplab, .mockctl, .frame,
   .note, .stand, header.top, footer) left behind. Product rules only.

   Written by the pages lane as its proposal and driven through a headless
   browser at 1180 / 375 / 320px before it landed here; the integrator moved it
   into public/ unchanged, because no lane owned the move and without it every
   screen in the flow ships unstyled. Served as a static asset, so a request for
   it never invokes the Worker (framework/environment.md, the asset blind spot).

   THREE DELIBERATE CHANGES FROM THE MOCK, each named:

   1. .codelbl - the mock's one inline style
      (style="display:block;margin-top:18px" on the recovery field's label).
      The CSP on the built pages forbids an inline style attribute, so it
      becomes a class.
   2. .live - new. The polite region a successful ceremony announces into
      before the form submits. The reserved min-height is not decoration:
      without it the card foot jumps at the moment it speaks, which is the
      same layout-shift fault .gatehint was given a min-height for.
   3. .codegrid gets grid-auto-flow:column with grid-template-rows:repeat(5,auto),
      and returns to grid-auto-flow:row at 680px. The mock produces its two
      columns of five by interleaving the DOM (01,06,02,07,...), which reads
      correctly at desktop and scrambles to 01,06,02,07 down the page at phone
      width where the grid collapses to one column. The built page emits the
      codes in their natural order and lets the grid do the column fill:
      identical at desktop, correct on a phone.

   THE WEB FONT, SELF-HOSTED. The mock loads Barlow and Barlow Semi Condensed
   from fonts.googleapis.com; the built pages must not, and the objection is
   not CSP hygiene. A remote font makes the founder's browser call Google on
   the sign-in screen, handing a third party the IP address and the timing of
   every sign-in - the same objection the design spec already uses to rule a
   remote logo off the consent screen. So the faces are served from this
   origin, and the policy gains font-src 'self' rather than a Google host.

   REQUIRED IN src/auth/pages.js (another lane owns that file): the
   Content-Security-Policy needs `font-src 'self'` added. Without it these
   @font-face rules are blocked and the page falls back to the system sans
   SILENTLY - which is exactly how the missing font went unnoticed the first
   time. If the type below ever looks wrong, check the policy first. */

/* Barlow and Barlow Semi Condensed, Jeremy Tribby, Copyright 2017 The Barlow
   Project Authors (https://github.com/jpt/barlow). SIL Open Font License 1.1
   - full text in public/fonts/OFL.txt, which is the OFL.txt shipped in
   google/fonts (ofl/barlow and ofl/barlowsemicondensed; byte-identical in
   both). The OFL permits redistribution of the font software, bundled or
   standalone; the reserved-name and no-sale clauses are the ones to keep in
   view if these files are ever renamed or resold, and neither is engaged by
   serving them unmodified from our own origin.

   PROVENANCE: the woff2 files are Google Fonts' own subsets, fetched
   2026-08-07 from the fonts.gstatic.com URLs that
   `https://fonts.googleapis.com/css2?family=Barlow:wght@400;600&family=Barlow+Semi+Condensed:wght@600&display=swap`
   returns to a Chrome user agent (Barlow v13, Barlow Semi Condensed v16).
   Verified as woff2 by their wOF2 signature. Downloading them at build time
   is not the thing being avoided above - what is avoided is the USER's
   browser making that request.

   ONLY THE WEIGHTS THIS STYLESHEET ACTUALLY USES. The mock asks Google for
   eight faces (Barlow 300/400/500/600, Semi Condensed 400/500/600/700); the
   product rules below use three: Barlow 400 (body), Barlow 600 (buttons and
   every b inside .meta, .err and .safety), and Barlow Semi Condensed 600 (the
   wordmark and the card h1). Nothing here is italic and nothing asks for a
   weight that is not defined, so the browser never has to synthesize a face.
   Two subsets each - latin, and latin-ext for a handle or a name carrying an
   accent - which is 6 files and 76,716 bytes total. Vietnamese was dropped;
   nothing in this flow renders Vietnamese, and a browser that meets one falls
   back rather than breaking.

   font-display:swap on every face. Text is painted immediately in the
   fallback and reflows when the face arrives: on a sign-in screen a visible
   string beats a correct one, and the alternative (block) is a blank card for
   up to three seconds on a bad connection. */

@font-face{font-family:'Barlow';font-style:normal;font-weight:400;font-display:swap;
  src:url(/fonts/barlow-400-latin.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD}
@font-face{font-family:'Barlow';font-style:normal;font-weight:400;font-display:swap;
  src:url(/fonts/barlow-400-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,
    U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,
    U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Barlow';font-style:normal;font-weight:600;font-display:swap;
  src:url(/fonts/barlow-600-latin.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD}
@font-face{font-family:'Barlow';font-style:normal;font-weight:600;font-display:swap;
  src:url(/fonts/barlow-600-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,
    U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,
    U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Barlow Semi Condensed';font-style:normal;font-weight:600;
  font-display:swap;
  src:url(/fonts/barlow-semicondensed-600-latin.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD}
@font-face{font-family:'Barlow Semi Condensed';font-style:normal;font-weight:600;
  font-display:swap;
  src:url(/fonts/barlow-semicondensed-600-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,
    U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,
    U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

:root{
  --bg:#0b1318; --surface:#111c24; --raised:#172230; --sunk:#0d151b;
  --border:rgba(255,255,255,0.09); --border-2:rgba(255,255,255,0.05);
  --text:#dce8f0; --text-2:#93b2c0; --text-3:#6a8797;
  --lake:#4a9abf; --spruce:#3d7a6a; --sand:#a08a68;
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --sans:'Barlow',-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;
  --disp:'Barlow Semi Condensed','Barlow',-apple-system,sans-serif;
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
body{background:var(--bg);color:var(--text);font-family:var(--sans);
  font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased}
a{color:var(--lake)}
[hidden]{display:none !important}
/* Carried onto every flex row that can hold a long unbreakable token - a
   client id metadata URL, a callback address, an MCP endpoint. A flex item
   defaults to min-width:auto and will not shrink below its max-content width,
   and on the consent screen that width is a whole URL on one line. */
.amast > *,.claim > *{min-width:0}

/* THE HOUSE HAD NO FOCUS STYLE. These screens are the first a person
   operates and keyboard-only operation is a hard acceptance criterion.
   Lake at 2px, offset 2px so the ring sits on the page ground rather than
   inside a lake-filled button where it would be invisible against itself.
   6.0:1 on --bg, 5.6:1 on --surface, 5.8:1 on --sunk; SC 2.4.11 wants 3:1. */
:focus{outline:2px solid var(--lake);outline-offset:2px;border-radius:3px}
:focus:not(:focus-visible){outline:none}
:focus-visible{outline:2px solid var(--lake);outline-offset:2px}

.authpage{max-width:560px;margin:0 auto;padding:0 40px 44px}
.authpage.wide{max-width:640px}

/* A fourth masthead, deliberately smaller than the other three. The wordmark
   is a span and not an anchor - a signed-out user, or one inside a popup, has
   nowhere to go. The origin string is IDENTIFICATION, NOT A SECURITY CLAIM:
   it exists because a webview may have no address bar, and it never gets a
   lock glyph and never gets the word secure. */
.amast{display:flex;align-items:baseline;gap:14px;padding:34px 0 16px;
  border-bottom:1px solid var(--border);flex-wrap:wrap}
.awordmark{font-family:var(--disp);font-size:26px;font-weight:600;letter-spacing:.01em;
  line-height:1;color:var(--text)}
.aorigin{font-family:var(--mono);font-size:12.5px;color:var(--text-3);margin-left:auto}

.acard{background:var(--surface);border:1px solid var(--border);border-radius:8px;
  padding:28px 30px 26px;margin-top:26px}
.lbl{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3)}
.acard h1{font-family:var(--disp);font-size:30px;font-weight:600;letter-spacing:.01em;
  line-height:1.1;margin-top:7px}
.lede{color:var(--text-2);font-size:15px;margin-top:11px}
.lede + .lede{margin-top:10px}
.meta{background:var(--sunk);border:1px solid var(--border);border-radius:7px;
  padding:13px 15px;font-size:14px;color:var(--text-2);line-height:1.6;margin-top:16px}
.meta b{color:var(--text);font-weight:600}
.meta.pre{margin-top:0;margin-bottom:18px}

/* THE ACTION STACK. Full-width rectangles, identical type size and weight,
   ten pixels apart, one column, at every width. Height only ever differs by a
   second line of copy - never by fill or border. */
.acts{margin-top:22px;display:grid;gap:10px}
.acts button,.acts a.btn{border-radius:5px;padding:14px 12px;font-family:var(--sans);
  font-size:15px;font-weight:600;cursor:pointer;line-height:1.25;width:100%;
  text-align:center;text-decoration:none;display:block}
/* The 1px transparent border on .primary is load-bearing: a filled button with
   border:0 and an outlined one with a 1px hairline are not the same rectangle,
   so without it Continue GREW 2px at the moment the gate opened and everything
   below it jumped. */
.primary{background:var(--lake);color:#04121a;border:1px solid transparent}
.second{background:transparent;color:var(--text);border:1px solid var(--border)}
.acts .sub{display:block;font-weight:400;font-size:11.5px;opacity:.82;margin-top:3px}
.primary.shut{background:transparent;color:var(--text-3);border:1px solid var(--border)}
.gatehint{margin-top:9px;font-size:13px;color:var(--sand);text-align:center;
  min-height:1.55em}
/* NEW - the polite region a successful ceremony announces into. It must be in
   the DOM at load (a live region created with its text already in it is a
   region screen readers routinely miss) but it must take NO SPACE while it is
   empty, or every ceremony screen carries a permanent 30px hole the mock does
   not have. :empty keeps it in the DOM and out of the layout; it grows only
   when it speaks, immediately before the form navigates away. */
.live{margin-top:10px;font-size:13px;color:var(--text-3);text-align:center;
  min-height:1.55em}
.live:empty{margin-top:0;min-height:0}

.alt{margin-top:20px;padding-top:16px;border-top:1px solid var(--border-2)}
.more{display:inline-block;font-size:13px;font-family:var(--mono);text-decoration:none;
  color:var(--lake)}
.altsub{margin-top:5px;font-size:12.5px;color:var(--text-3)}
.cardfoot{margin-top:18px;padding-top:15px;border-top:1px solid var(--border-2);
  font-size:13px;color:var(--text-3)}
.foot{margin-top:22px;font-size:13px;color:var(--text-3)}

/* THE INLINE ERROR REGION. The .safety treatment at a smaller budget -
   SAND, NOT RED. The house has no red and none is introduced. A passkey that
   did not finish is not an alarm; it is a fact about the last five seconds. */
.err{margin-top:16px;background:rgba(160,138,104,.07);
  border:1px solid rgba(160,138,104,.42);border-left-width:3px;border-radius:6px;
  padding:14px 16px;font-size:14.5px;color:var(--text-2);line-height:1.6}
.err b{color:var(--text);font-weight:600;display:block}

/* NEW - was style="display:block;margin-top:18px" inline on the mock. */
.codelbl{display:block;margin-top:18px}
/* NEW - for the two throwaway elements public/auth.js creates to copy and to
   download. A class rather than element.setAttribute('style', ...), which the
   Content-Security-Policy on these pages refuses. */
.offscreen{position:fixed;top:-1000px;left:-1000px;opacity:0}
.codefield{margin-top:16px}
.codefield input{width:100%;background:var(--sunk);border:1px solid var(--border);
  border-radius:6px;padding:15px 16px;color:var(--text);font-family:var(--mono);
  font-size:19px;letter-spacing:.06em;font-variant-numeric:tabular-nums}
.codefield input::placeholder{color:var(--text-3);letter-spacing:.04em}
.codefield input:focus{border-color:var(--lake)}
.codehint{margin-top:8px;font-size:12.5px;color:var(--text-3);font-family:var(--mono)}

/* the lead sits ABOVE the codes and in the present tense, on purpose: a
   warning underneath is read after the decision to scroll past it. */
.standfirst{font-size:18px;line-height:1.5;color:var(--text);margin-top:16px;
  border-left:2px solid var(--lake);padding-left:16px}

.codes{background:var(--sunk);border:1px solid var(--border);border-radius:8px;
  padding:18px 20px;margin-top:20px}
.codehead{display:flex;align-items:baseline;gap:14px;padding-bottom:12px;
  border-bottom:1px solid var(--border-2);flex-wrap:wrap}
.codehead > *{min-width:0}
.codeacts{margin-left:auto;display:flex;gap:10px;flex-wrap:wrap}
.codeacts button,.codeacts a{font-family:var(--mono);font-size:12.5px;color:var(--lake);
  text-decoration:none;border:1px solid var(--border);border-radius:4px;
  padding:6px 12px;background:transparent;cursor:pointer;line-height:1.3}
.codeacts button:hover,.codeacts a:hover{border-color:var(--lake)}
/* AMENDED - column fill by the grid rather than by interleaving the DOM, so
   the one-column phone layout reads 01..10 instead of 01,06,02,07,... */
.codegrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  grid-template-rows:repeat(5,auto);grid-auto-flow:column;gap:0 26px;margin-top:12px}
.codegrid > div{display:flex;align-items:baseline;gap:12px;padding:8px 0;
  border-bottom:1px solid var(--border-2)}
.codegrid .n{font-family:var(--mono);font-size:11px;color:var(--text-3);
  width:20px;flex:0 0 auto;font-variant-numeric:tabular-nums}
.codegrid .c{font-family:var(--mono);font-size:17px;letter-spacing:.06em;
  color:var(--text);font-variant-numeric:tabular-nums}

/* the house's strongest emphasis, spent once, on the page it exists for.
   One block, one border, two paragraphs. */
.safety{margin-top:20px;background:rgba(160,138,104,.07);
  border:1px solid rgba(160,138,104,.42);border-left-width:3px;border-radius:8px;
  padding:17px 19px;font-size:15px;line-height:1.6;color:var(--text-2)}
.safety b{color:var(--text);font-weight:600}
.safety p + p{margin-top:10px}

/* ==========================================================================
   THE CONSENT SCREEN (LDGR-0012). Lifted from design/mocks/connect-house.html
   with the mock's storyboard chrome left behind, exactly as the sign-in rules
   above were lifted from signin-house.html.

   THIS HALF SHIPPED MISSING ONCE AND THE FAILURE WAS INVISIBLE TO EVERY
   AUTOMATED CHECK. The consent renderer emitted .asker, .host, .claim,
   .selfsaid and the rest; this stylesheet had rules for none of them; so the
   screen rendered as a stack of identical unstyled paragraphs and still
   returned 200, still passed its tests, still carried every correct string.
   The hierarchy IS the security argument on this page - a reader tells the
   checked fact from the client's own claim by type size and nothing else - so
   the missing rules were the defect, not a polish item.

   ONE ADDITION THE MOCK DOES NOT HAVE: .nohost. The mock never drew the
   fourth row of the degradation table (no host and no name), because that
   state falls through to screen L1. The renderer keeps it as a second lock,
   and it must not wear the confident display treatment - a placeholder in the
   same 32px type as a verified host is the exact confusion this block exists
   to prevent. It renders in the muted colour, at the same size, so the
   hierarchy is intact and the confidence is not.
   ========================================================================== */

/* The bulleted capability list. Sign-in has no list, so this base rule comes
   across with the consent rules that use it. */
ul.rules{list-style:none;display:grid;gap:13px;max-width:104ch}
ul.rules li{padding-left:18px;position:relative;color:var(--text-2);font-size:15px}
ul.rules li::before{content:"";position:absolute;left:0;top:.66em;width:8px;height:2px;
  background:var(--lake)}
ul.rules b{color:var(--text);font-weight:600}

/* A raw address printed inside a .meta block - never a link. */
.meta .raw{font-family:var(--mono);font-size:12px;color:var(--text-3);word-break:break-all;
  display:block;margin-top:6px}

/* THE ASKER BLOCK. The host of the client_id URL is the largest thing on the
   page, and that is a vendor requirement rather than taste: Anthropic's
   connector documentation states that because the metadata document is
   self-asserted, the consent screen must display the host of the client_id
   URL - not the client_name field - as the relying party.

   The name is body copy in straight double quotes, because quotation marks
   are the universal typographic mark of reported speech. The SELF-DECLARED
   pill is sand, which in this system means a gap in the data - which is
   precisely what an unverified name is. It reads as a category label, not an
   alarm, and it survives CSS being off entirely: the text still says
   self-declared. */
.asker{margin-top:22px}
.host{font-family:var(--disp);font-size:32px;font-weight:600;letter-spacing:.01em;
  line-height:1.05;margin-top:7px;word-break:break-word}
.host.nohost{color:var(--text-3)}
.claim{display:flex;align-items:baseline;gap:10px;margin-top:9px;flex-wrap:wrap}
.claim .said{font-size:16px;color:var(--text-2)}
.claim .said b{font-family:var(--mono);color:var(--text);font-weight:500}
.selfsaid{display:inline-block;font-family:var(--mono);font-size:10px;
  letter-spacing:.11em;text-transform:uppercase;color:var(--sand);
  border:1px solid var(--sand);border-radius:2px;padding:2px 8px;flex:0 0 auto}
.claimwhy{margin-top:11px;font-size:14.5px;color:var(--text-2);max-width:60ch;
  line-height:1.6}
.claimwhy + .claimwhy{margin-top:9px}

/* WHAT IS BEING GRANTED. */
.grant{margin-top:22px}
.grant h2{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3);
  margin-top:20px}
.grant h2:first-child{margin-top:0}
.grant p.intro{font-size:15px;color:var(--text-2);margin-top:9px}
.grant ul.rules{margin-top:10px;gap:9px}
.grant ul.rules li{font-size:14.5px}
/* The negative block is one sentence and a div, not a list and not an h2: the
   list SHAPE is what invites roadmap-dependent bullets, and an eyebrow is a
   heading only where it heads a real list. */
.grant .neg{margin-top:20px}
.grant p.cannot{margin-top:10px;font-size:14.5px;color:var(--text-2);max-width:60ch;
  line-height:1.6}

.lasts{margin-top:20px;font-size:14.5px;color:var(--text-2)}
/* ORDINARY BODY TEXT, NOT A TINTED BOX. A box invites the reader to skip the
   privacy sentence as boilerplate, which is the one thing it cannot afford. */
.privacy{margin-top:18px;font-size:15px;color:var(--text-2);line-height:1.6}
.offswitch{margin-top:14px;font-size:13.5px;color:var(--text-2)}

/* DENY IS FIRST IN THE DOM AND THIS RULE IS WHY THAT IS SAFE. column-reverse
   puts the keyboard reader's first tab stop on the harmless option while a
   sighted reader's eye lands on the action that continues what they started.
   WITHOUT THIS RULE THE STACK SHIPS IN DOM ORDER AND DENY RENDERS ABOVE
   ALLOW, which inverts the design rather than merely unstyling it. The two
   buttons stay identical in width, type size and weight either way - that is
   .acts above, and it is what satisfies "deny as easy as approve". */
.acts.consent{display:flex;flex-direction:column-reverse}

/* The loopback warning. Same sand treatment as .err, and the one-per-page
   emphasis budget is spent here on that variant. */
.local{margin-top:18px;background:rgba(160,138,104,.07);
  border:1px solid rgba(160,138,104,.42);border-left-width:3px;
  border-radius:6px;padding:14px 16px;font-size:14px;color:var(--text-2);
  line-height:1.6}
.local h2{font-family:var(--sans);font-size:14px;color:var(--text);font-weight:600;
  margin-bottom:5px}
/* LDGR-0024: var(--text-3) measured 4.15:1 against this block's background on
   real Blink, WebKit and Gecko renders - short of the 4.5:1 WCAG AA floor for
   normal-size text by a small but real margin. var(--text-2) clears it at
   7.04:1 with no other change; this is the one piece of raw, checkable text
   on the whole screen (the redirect_uri a reader is asked to verify against
   what they just did), so it is not the place to leave a marginal figure. */
.local .u{font-family:var(--mono);font-size:12.5px;color:var(--text-2);
  display:block;margin-top:9px;word-break:break-all}

.termfoot{margin-top:22px;padding-top:16px;border-top:1px solid var(--border);
  font-size:13.5px;color:var(--text-2);line-height:1.6}

/* REFLOW. What does NOT move: the action stack, the code type size, and the
   single-column card. The codes stay at 17px mono because they are being
   transcribed. */
@media (max-width:680px){
  body{font-size:15px}
  .authpage{padding:0 18px 40px}
  .amast{padding:24px 0 14px}
  .acard{padding:22px 18px 20px}
  .acard h1{font-size:26px}
  .host{font-size:27px}
  .codes{padding:15px 15px}
  .codegrid{grid-template-columns:minmax(0,1fr);grid-template-rows:none;
    grid-auto-flow:row}
  .aorigin{margin-left:0;width:100%}
}
