/* =============================================================================
   labs.llc/dina/ — LOGO LAB — the paper edition
   -----------------------------------------------------------------------------
   The house sheet, in the register labs.llc uses — white paper, one ink, a
   great deal of air, and type doing the work — plus the furniture of one
   instrument: an artboard, two engines and their controls.

   The whole system is five decisions:

     ink      #1E262B   near-black with the blue left in, never pure #000
     paper    #FFFFFF
     deep     #11161C   the dark band / the footer
     line     a 12% ink hairline; there are no heavy borders anywhere
     measure  1265px

   This sheet is the LIGHT edition and the canonical one. The dark edition is
   assets/css/dark.css: an override sheet scoped to html[data-dark], loaded
   after this one, holding nothing but the literals this file could not express
   as tokens. Nothing in this file may be edited to serve the dark edition.

   THE ARTBOARD IS THE EXCEPTION AND IT IS DELIBERATE. Everything from
   "THE LOGO LAB" down draws on a ground the READER chose — white, black, a
   transparent checkerboard, the page, the deep tone — and that ground must not
   move when the edition does, or the lab stops being a place to judge a mark.
   Those rules therefore name literal colours on purpose. They are listed at
   the bottom of dark.css so the next person knows they were not missed.

   THE ONE RULE elsewhere: prefer a token. A declaration that reads var(--ink)
   or var(--line) is already correct in both editions.
   ========================================================================== */

/* ------------------------------------------------------------------ webfont
   DM Sans, self-hosted, the same two files labs.llc serves. It used to be an
   @import of fonts.googleapis.com sitting at the top of an inline <style> —
   which is the worst of every option: a render-blocking stylesheet, on a
   third-party origin, discovered only after the HTML parser reached the middle
   of the document, in a page that otherwise made no network request at all
   before first paint.

   Variable across both axes the sheet uses (opsz 9-40, wght 200-700), so the
   four-weight inversion the design rests on is 94KB of woff2 rather than
   twelve separate faces. Split on the same unicode ranges Google splits on, so
   a page of English never downloads the accented block. */
@font-face {
    font-family: 'DM Sans';
    font-style: normal;
    font-weight: 200 700;
    font-display: swap;
    src: url('../fonts/dm-sans-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: 'DM Sans';
    font-style: normal;
    font-weight: 200 700;
    font-display: swap;
    src: url('../fonts/dm-sans-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 {
    --ink:        #1E262B;
    --ink-77:     rgba(30, 38, 43, .77);
    /* The secondary ink, at .64 rather than .55. .55 measures 3.6:1 on the
       paper, under the 4.5:1 body-text floor, and this token carries most of
       the small type on the site: every eyebrow, every field label, every
       registrar name, the whole of the results table's second line. At .64 it
       measures 4.7:1 and is still plainly the quieter of the two inks. */
    --ink-55:     rgba(30, 38, 43, .64);
    --paper:      #ffffff;
    --tint:       #FAFAFA;  /* recessed panel ground, added for Network Labs */
    --deep:       #11161C;
    --deep-soft:  #171E26;
    --line:       rgba(30, 38, 43, .12);
    --line-soft:  rgba(30, 38, 43, .07);
    /* The inverse hairline: for rules drawn ON the deep band while the page
       itself is light. The dark edition has to flip this one the other way or
       those rules draw white on white. */
    --line-dark:  rgba(255, 255, 255, .13);
    --muted:      #717171;

    /* DomainChaos was #ff8800 throughout — a screen orange, chosen against
       #0a0a0a. It measures 2.1:1 on white, so on paper it is not an accent, it
       is a highlighter. The lineage survives as the burnt print red of the
       same family; the dark edition takes it back up to #F97316, which is the
       original orange one step calmer and holds on the deep ground. Used for
       hairlines, eyebrows and live indicators only — never as a large fill. */
    --accent:     #C2410C;
    /* The accent as a FILL, with dark type on it. Inking a colour is right for
       type and wrong for a solid block, so the two are separate tokens and the
       fill keeps its saturation. */
    --accent-fill: #FB923C;
    --on-accent:  #2A1206;

    /* ------------------------------------------------------------- semantics
       The status of a domain is the one place this site needs colour to carry
       meaning, so these four are the only hues besides the accent.

       Every one of them is three steps down its scale from where a dark-ground
       palette would put it. #00cc66 — the old build's "AVAILABLE" — measures
       1.8:1 on white; at #15803D it is 4.9:1 and still unmistakably green. The
       dark edition moves all four back up; see dark.css. */
    --free:       #15803D;   /* available            */
    --taken:      #B91C1C;   /* registered           */
    --unsure:     #B45309;   /* could not determine  */
    --info:       #1D4ED8;   /* links, social        */
    --free-wash:   rgba(21, 128, 61, .07);
    --taken-wash:  rgba(185, 28, 28, .06);
    --unsure-wash: rgba(180, 83, 9, .07);

    --measure:    1265px;
    --gutter:     clamp(20px, 5vw, 56px);

    /* The height of the sticky header, published as a token because two things
       have to agree about it: the header, and every anchor target on the page.
       A heading scrolled to the top of the viewport lands underneath a sticky
       bar unless something subtracts the bar first. */
    --nav-h:      74px;
    --band:       clamp(64px, 9vw, 128px);
    --ease:       cubic-bezier(.22, .61, .36, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* Applied to anything with an id rather than to a hand-kept list of sections:
   a scroll margin costs nothing on an element nobody ever scrolls to, and a
   list is a thing to forget to update. */
[id] { scroll-margin-top: calc(var(--nav-h) + 14px); }

body {
    margin: 0;
    background: var(--paper);
    color: var(--ink-77);
    font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
                 Helvetica, Arial, sans-serif;
    font-size: 17px;
    line-height: 1.62;
    /* R4: the floor, by inheritance. Set the base readable and thin only what
       is deliberately large. The opposite order leaks — anything with no class
       of its own inherits the thin weight from a wrapper, and you end up with
       11px labels at weight 300 that you cannot find a rule for. */
    font-weight: 400;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 { color: var(--ink); margin: 0; font-weight: 600; }

.d1 {
    font-size: clamp(2.1rem, 5.2vw, 3.9rem);
    font-weight: 200; letter-spacing: -.035em; line-height: 1.09;
}
.d2 {
    font-size: clamp(1.75rem, 3.5vw, 2.77rem);
    font-weight: 600; letter-spacing: -.04em; line-height: 1.06;
}
/* The eyebrow. Every band opens with one; it is the only place small-caps
   tracking appears, so it reads as a system label rather than as text. 700,
   because tracking thins a face further and 500 at this size on paper is a
   smear. */
.eyebrow {
    display: flex; align-items: center; gap: .7rem;
    font-size: .688rem; font-weight: 700;
    letter-spacing: .19em; text-transform: uppercase;
    color: var(--ink-55);
    margin: 0 0 1.6rem;
}
.eyebrow::before { content: ''; width: 26px; height: 1px; background: var(--accent); flex: 0 0 auto; }

.lede {
    font-size: clamp(1.02rem, 1.35vw, 1.19rem);
    line-height: 1.6; font-weight: 300; color: var(--ink-77);
    max-width: 62ch;
}
.lede + .lede { margin-top: 1rem; }

a { color: inherit; }

.wrap { max-width: var(--measure); margin: 0 auto; padding-inline: var(--gutter); }
.band { padding-block: var(--band); }

/* THE DEEP BAND IS GONE. The shell used .band--deep to re-declare the ink
   tokens on a dark ground for a band in the middle of a light page. This page
   has no such band: the only deep surface on it is the footer, which sets its
   own colours, and the dark edition is a whole document rather than a stripe.
   Its .btn, .btn--ghost and .seg__b overrides went with it. */
.band--tint { background: #FAFAFA; }
.rule { height: 1px; background: var(--line); border: 0; margin: 0; }

/* =============================================================================
   NAV
   ========================================================================== */

.nav {
    position: sticky; top: 0; z-index: 60;
    background: rgba(255, 255, 255, .86);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid var(--line-soft);
}
.nav__in {
    max-width: var(--measure); margin: 0 auto; padding: 0 var(--gutter);
    height: var(--nav-h); display: flex; align-items: center; gap: 1rem;
}
.nav__mark { display: flex; align-items: center; gap: .8rem; text-decoration: none; margin-right: auto; }
/* The mark. No box, no ring, no fill.

   The old build ringed a photographic disc in 4px of orange with a 45px glow;
   the rewrite before this one swapped that for a hairline and a border-radius,
   which was quieter but was still a circle drawn around a logo that already had
   one. Two edges, concentric, neither of them content.

   A wordmark on paper needs no edge at all: the letterforms are the shape, and
   the thing that separates them from the page is the page. Height is set here
   and width is left to the viewBox so the 86:24 proportion cannot be squashed
   the way an <img> with two hard attributes squashed the old one.

   The colour is inherited, not declared — currentColor in the SVG picks up
   whatever --ink resolves to in this edition, which is the entire reason it can
   be one file for both. */
/* The mark is a <div> of two links now — the labs.llc plate and the local
   wordmark — so each half re-declares the flex row the single anchor used to
   be. The plate's height is set here and its width left to the 189:80 ratio,
   for the same no-squashing reason as the wordmark above. */
.nav__mark a { display: flex; align-items: center; gap: .8rem; text-decoration: none; }
.nav__plate { display: block; height: 28px; width: auto; }
.nav__mark b {
    font-size: .95rem; font-weight: 600; letter-spacing: -.03em; color: var(--ink);
}
.nav__mark span {
    font-size: .6rem; font-weight: 700; letter-spacing: .32em;
    text-transform: uppercase; color: var(--ink-55);
    padding-left: .8rem; border-left: 1px solid var(--line);
}
@media (max-width: 980px) { .nav__mark span { display: none; } }

.nav__links { display: flex; align-items: center; gap: 1.9rem; }
@media (max-width: 1100px) { .nav__links { display: none; } }
.nav__links a {
    text-decoration: none; font-size: .875rem; font-weight: 500;
    color: var(--ink-77); letter-spacing: -.01em; position: relative; padding-block: .4rem;
}
.nav__links a::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0;
    height: 1px; background: var(--ink); transform: scaleX(0); transform-origin: left;
    transition: transform .32s var(--ease);
}
.nav__links a:hover::after, .nav__links a[aria-current]::after { transform: scaleX(1); }
.nav__links a[aria-current] { color: var(--ink); }

/* ---------------------------------------------------------------------------
   THE EDITION PILL

   Lifted whole from labs.llc, because it is the same control doing the same
   job and a visitor who has met one should not have to learn the other. Two
   editions of this page — this one, paper, and indexdark.html — and the pill
   is where a visitor moves between them.

   Deliberately a segmented control rather than another nav link: the two are
   alternatives to each other, not destinations alongside Generator and
   Registrars, and a segmented control is the one shape that says so without a
   word of explanation.

   Exactly one segment carries .is-on, and it is written into the markup rather
   than worked out at runtime, because on any given page the answer is a
   constant: this file is always the light one. tools/mkdark.py moves it.

   The moving part is a single thumb behind both segments, not a background on
   whichever segment is lit. That is what lets it slide: on hover it travels to
   the segment under the cursor and previews the switch before the click.
   ------------------------------------------------------------------------ */
.mode-pill {
    position: relative; flex: 0 0 auto;
    display: inline-flex; align-items: center;
    padding: 3px; border-radius: 999px;
    border: 1px solid var(--line);
    /* A shallow well, so the thumb reads as sitting in the track rather than
       floating on the navbar. Both values are ink at single digits of alpha. */
    background: linear-gradient(180deg, rgba(30,38,43,.045), rgba(30,38,43,.025));
    box-shadow: inset 0 1px 2px rgba(30, 38, 43, .055);
}
.mode-pill__thumb {
    position: absolute; z-index: 0;
    top: 3px; bottom: 3px; left: 3px; width: calc(50% - 3px);
    border-radius: 999px; background: var(--ink);
    box-shadow: 0 1px 2px rgba(30, 38, 43, .26), 0 6px 18px rgba(30, 38, 43, .14);
    transition: transform .42s var(--ease);
}
/* Which half is lit. The class is on the container and written into the
   markup: on any one page the answer never changes. */
.mode-pill--dark .mode-pill__thumb { transform: translateX(100%); }

/* Hover preview. There are exactly two segments, so "the unlit one is hovered"
   already says which side the thumb belongs on and the rule needs no position
   selector — which matters, because the lit segment is a <span> and the unlit
   one an <a>, and a :first-of-type / :last-of-type pair counts types. Where
   :has is unsupported the pill simply does not preview, which costs nothing. */
.mode-pill:has(.mode-pill__seg:not(.is-on):hover) .mode-pill__thumb { transform: translateX(100%); }
.mode-pill--dark:has(.mode-pill__seg:not(.is-on):hover) .mode-pill__thumb { transform: none; }

.mode-pill__seg {
    position: relative; z-index: 1;
    display: inline-flex; align-items: center; justify-content: center;
    /* Both segments hold the same width, because the thumb is half the track
       and an uneven split would leave it short of one end. */
    min-width: 2.5rem; padding: .4rem .45rem; border-radius: 999px;
    text-decoration: none; color: var(--ink-55);
    transition: color .32s var(--ease);
}
/* The lit segment is a <span>, not a link — it is the page you are already on,
   and a link to here is a reload that costs a round trip and returns the same
   document. */
.mode-pill__seg.is-on { color: var(--paper); cursor: default; }
/* The fallback where :has is missing and the thumb therefore cannot move: the
   unlit segment darkens in place. It must not go to paper — with no thumb
   underneath, paper on the track is a label that vanishes. */
.mode-pill__seg:not(.is-on):hover { color: var(--ink); }
/* While a segment is hovered the thumb is under IT, so the lit colour follows
   the thumb rather than the class. Equal specificity, later wins. */
.mode-pill:has(.mode-pill__seg:hover) .mode-pill__seg.is-on { color: var(--ink-55); }
.mode-pill:has(.mode-pill__seg:hover) .mode-pill__seg:hover { color: var(--paper); }
.mode-pill__seg:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* 13px, and the same 13 is written on the <svg> tag itself as width and
   height. That duplication is the point: an SVG with a viewBox and no
   dimensions of its own falls back to 300x150 when no stylesheet reaches it. */
.mode-pill__i { width: 13px; height: 13px; flex: 0 0 auto; display: block; }

@media (prefers-reduced-motion: reduce) { .mode-pill__thumb { transition: none; } }

/* The hamburger. At every width — it opens the whole menu rather than a fold
   of the header, so on a wide screen the navbar's section links and the menu's
   tools are two different offers rather than the same one twice. */
.nav__burger {
    display: flex; width: 40px; height: 40px; padding: 0;
    background: transparent; border: 1px solid var(--line); border-radius: 8px;
    cursor: pointer; align-items: center; justify-content: center;
    color: var(--ink);
    transition: border-color .24s var(--ease);
}
.nav__burger:hover { border-color: var(--ink); }
.nav__burger svg { display: block; }
/* transform-box: view-box puts the origin in the icon's own coordinate space
   rather than on the line's own zero-height box, and the translate has to come
   second — CSS applies transform functions right to left. */
.nav__burger line {
    transform-box: view-box; transform-origin: 9px 6px;
    transition: transform .28s var(--ease);
}
.nav__burger[aria-expanded="true"] .nav__burger-t { transform: rotate(45deg) translateY(2.5px); }
.nav__burger[aria-expanded="true"] .nav__burger-b { transform: rotate(-45deg) translateY(-2.5px); }
@media (prefers-reduced-motion: reduce) { .nav__burger line { transition: none; } }

/* THE HEADER ON A PHONE. Three things have to fit inside 335 usable pixels at
   375 and 280 at 320: the mark, the edition pill, and the way into the rest of
   the site. Everything here is measured against those two numbers. */
@media (max-width: 1100px) { .nav__in { gap: .9rem; } }
@media (max-width: 640px) {
    :root { --nav-h: 62px; }
    .nav__in { gap: .55rem; }
    .nav__mark b { font-size: .86rem; }
    /* A segment is a glyph in a box, and the box is the tap target. The glyph
       stays at 13px — it is meant to be small — and what grows is the box. */
    .mode-pill__seg { min-width: 1.9rem; padding: .58rem .4rem; }
    /* No ring on a phone: the burger is the only thing in that corner and the
       outline was the heaviest object in the bar for no work it was doing.
       44px is the smallest a finger reliably hits. */
    .nav__burger { width: 44px; height: 44px; border-color: transparent; }
    .nav__burger:hover { border-color: transparent; }
    .nav__in > .btn { display: none; }
}
/* THE SAME ARGUMENT THE FIELD BELOW MAKES, APPLIED TO THE BAR. A phone held
   sideways is 844px (iPhone 14/15) or 932px (Pro Max) wide, so the 640px query
   above never matches it — measured in landscape, the burger was 40x40 and the
   pill segment 30x32, and those are the only two controls left in the bar on a
   phone. The pill's glyph stays at 13px, per the house note on its geometry:
   what grows is the box. flex: 0 0 auto because the burger is an unflexed item
   in .nav__in and shrank two pixels below its own declared 44 at 390px. */
@media (hover: none) and (pointer: coarse) {
    .nav__burger { width: 44px; height: 44px; flex: 0 0 auto; }
    .mode-pill__seg { min-height: 44px; }
}
@media (max-width: 380px) { .nav__mark b { display: none; } }

/* =============================================================================
   THE MENU
   ========================================================================== */
.menu[hidden] { display: none; }
.menu {
    position: fixed; inset: 0; z-index: 200; display: block;
    /* Clipped: on the way out the scroll lock is released the instant close()
       runs while the panel is still travelling, and an unclipped panel sitting
       outside the viewport for those 360ms is a horizontal scrollbar that
       appears and leaves for no visible reason. */
    overflow: hidden;
}
.menu__scrim {
    position: absolute; inset: 0;
    /* A scrim exists to dim what is behind it, so it stays dark in both
       editions — see R2. It is the one black wash on this sheet that the dark
       edition does not re-polarise. */
    background: rgba(17, 22, 28, .38);
    -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
    opacity: 0; transition: opacity .32s var(--ease);
}
.menu.is-open .menu__scrim { opacity: 1; }
.menu__panel {
    position: absolute; top: 0; right: 0; height: 100%;
    width: 100%; max-width: 404px;
    background: var(--paper);
    border-left: 1px solid var(--line);
    box-shadow: -24px 0 60px rgba(30, 38, 43, .10);
    display: flex; flex-direction: column;
    transform: translateX(100%);
    transition: transform .36s var(--ease);
}
.menu.is-open .menu__panel { transform: none; }
/* The panel takes focus itself on open so a screen reader reads the dialog's
   label. It is a container, not a control, and the sheet-wide :focus-visible
   rule was drawing a 2px accent ring around all 404 pixels of it. */
.menu__panel:focus, .menu__panel:focus-visible { outline: none; }
@media (prefers-reduced-motion: reduce) { .menu__scrim, .menu__panel { transition: none; } }

.menu__head {
    flex: 0 0 auto; height: 74px;
    display: flex; align-items: center; gap: .8rem;
    padding: 0 1.15rem 0 1.4rem;
    border-bottom: 1px solid var(--line-soft);
}
.menu__logo { display: block; height: 24px; width: auto; }
.menu__title {
    font-size: .6rem; font-weight: 700; letter-spacing: .3em; text-transform: uppercase;
    color: var(--ink-55); padding-left: .8rem; border-left: 1px solid var(--line);
    margin-right: auto;
}
.menu__x {
    width: 34px; height: 34px; flex: 0 0 auto; padding: 0;
    display: flex; align-items: center; justify-content: center;
    background: transparent; border: 1px solid var(--line); border-radius: 8px;
    color: var(--ink-55); cursor: pointer;
    transition: border-color .24s var(--ease), color .24s var(--ease);
}
.menu__x:hover { border-color: var(--ink); color: var(--ink); }
.menu__x svg { width: 13px; height: 13px; }
@media (max-width: 640px) { .menu__x { width: 44px; height: 44px; } }

.menu__search {
    flex: 0 0 auto; position: relative;
    padding: .9rem 1.4rem;
    border-bottom: 1px solid var(--line-soft);
    background: var(--paper);
}
.menu__search svg {
    position: absolute; left: 2.05rem; top: 50%; transform: translateY(-50%);
    width: 13px; height: 13px; color: var(--ink-55); pointer-events: none;
}
.menu__q {
    font: inherit; font-size: .88rem; font-weight: 500; width: 100%;
    padding: .6rem 2.1rem .6rem 2.05rem;
    color: var(--ink); background: rgba(30, 38, 43, .035);
    /* --line is a rule between two things that are already there; a text input
       is a box that has to announce itself, so it gets a real border. */
    border: 1px solid rgba(30, 38, 43, .52); border-radius: 8px;
    transition: border-color .24s var(--ease), background .24s var(--ease);
    -webkit-appearance: none; appearance: none;
}
.menu__q::placeholder { color: var(--ink-55); font-weight: 400; }
.menu__q::-webkit-search-cancel-button { display: none; }
.menu__q:focus { outline: none; border-color: var(--ink); background: var(--paper); }
.menu__q:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Safari on iOS zooms the page when a focused input is under 16px, and a zoomed
   page carries the 404px panel — and the field that was just tapped — off the
   visual viewport. 16px is the threshold at which it does not, so the field
   takes it wherever the zoom can happen. Matched on the pointer rather than on
   a width: a phone held sideways is 932px wide and still zooms. */
@media (hover: none) and (pointer: coarse) {
    .menu__q { font-size: 16px; }
    /* The principle was applied to the input and not to the two buttons around
       it: the drawer's close measured 34x34 in landscape and the search clear
       22x22 at EVERY width, portrait included. .menu__clear is absolutely
       positioned, so growing it moves no other box. */
    .menu__x, .menu__clear { width: 44px; height: 44px; }
}
.menu__clear {
    position: absolute; right: 2rem; top: 50%; transform: translateY(-50%);
    width: 22px; height: 22px; padding: 0; display: flex;
    align-items: center; justify-content: center;
    background: transparent; border: 0; border-radius: 6px;
    color: var(--ink-55); cursor: pointer;
}
.menu__clear[hidden] { display: none; }
.menu__clear:hover { color: var(--ink); background: rgba(30, 38, 43, .06); }
.menu__clear svg { width: 10px; height: 10px; }

.menu__count {
    flex: 0 0 auto; margin: 0; padding: .55rem 1.4rem 0;
    font-size: .62rem; font-weight: 700; letter-spacing: .18em;
    text-transform: uppercase; color: var(--ink-55);
}
.menu__count b { color: var(--ink); font-weight: 700; }
.menu__count[data-filtered="1"] b { color: var(--accent); }

.menu__body { flex: 1 1 auto; overflow-y: auto; padding: 1.1rem 1.4rem 1.6rem; }
.menu__sec + .menu__sec { margin-top: 1.7rem; }
.menu__sec[hidden] { display: none; }
.menu__h {
    display: flex; align-items: center; gap: .8rem;
    font-size: .6rem; font-weight: 700; letter-spacing: .22em; text-transform: uppercase;
    color: var(--ink-55); margin: 0 0 .5rem;
}
.menu__h::after { content: ''; height: 1px; background: var(--line); flex: 1 1 auto; }
.menu__row {
    display: flex; align-items: baseline; gap: .7rem;
    padding: .62rem 0; border-bottom: 1px solid var(--line-soft);
    text-decoration: none; color: var(--ink-77);
    transition: padding-left .2s var(--ease), color .2s var(--ease);
}
.menu__row:hover { color: var(--ink); padding-left: .5rem; }
.menu__row[hidden] { display: none; }
.menu__row:last-child { border-bottom: 0; }
.menu__l { flex: 1 1 auto; min-width: 0; }
.menu__l b { display: block; font-size: .9rem; font-weight: 600; letter-spacing: -.015em; color: var(--ink); }
.menu__l span { display: block; font-size: .74rem; font-weight: 400; color: var(--ink-55); line-height: 1.4; }
.menu__go { flex: 0 0 auto; color: var(--ink-55); font-size: .8rem; font-style: normal; }
.menu__empty { margin: 1.4rem 0 0; text-align: center; font-size: .82rem; color: var(--ink-55); }
.menu__empty[hidden] { display: none; }

.menu__foot {
    flex: 0 0 auto; padding: 1rem 1.4rem;
    border-top: 1px solid var(--line-soft); background: var(--paper);
    display: flex; justify-content: center;
}
/* The footer's copy of the pill is the same control, so it is the same size: a
   segmented pill held to its own width and centred, one step larger than the
   header's because a panel footer has the room. Stretched to the full width of
   the panel it reads as a broken button rather than as the pill above. */
.menu__foot .mode-pill { display: inline-flex; width: auto; }
.menu__foot .mode-pill__seg { flex: 0 0 auto; min-width: 3.6rem; padding: .6rem .8rem; }
@media (max-width: 460px) { .menu__panel { max-width: 100%; } }

/* =============================================================================
   BUTTONS
   ========================================================================== */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .6rem;
    font: inherit; font-size: .82rem; font-weight: 600; letter-spacing: .02em;
    padding: .72rem 1.15rem; border-radius: 8px;
    border: 1px solid transparent; background: var(--ink); color: #fff;
    text-decoration: none; cursor: pointer;
    transition: background .25s var(--ease), color .25s var(--ease),
                border-color .25s var(--ease), transform .25s var(--ease);
}
.btn:hover { background: #000; transform: translateY(-1px); }
.btn:active { transform: none; }
.btn[disabled] { opacity: .45; cursor: not-allowed; transform: none; }
/* One button on the page — "The contents", in the hero — so the ghost, small
   and outline modifiers the shell carried are gone with the pages that used
   them. */

/* =============================================================================
   HERO
   ========================================================================== */
.hero { padding-block: clamp(52px, 8vw, 104px) clamp(40px, 6vw, 72px); }
.hero__in { max-width: 46rem; }
.hero h1 { margin-bottom: 1.5rem; }
/* The one line under the hero: what the page is, in figures. The shell used
   this class for a row of three big counts; here it is a sentence, so it is
   set as one. */
.hero__fact {
    margin-top: 2.6rem; padding-top: 1.6rem; border-top: 1px solid var(--line);
    font-size: .72rem; font-weight: 700; letter-spacing: .14em;
    text-transform: uppercase; color: var(--ink-55);
}

/* =============================================================================
   FOOTER
   ========================================================================== */
.foot { border-top: 1px solid var(--line-dark); background: var(--deep); color: rgba(255, 255, 255, .5); }
.foot__in { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 2rem; padding-block: 2.2rem; }
.foot__in p { margin: 0; font-size: .78rem; }
.foot__links { display: flex; flex-wrap: wrap; gap: 1.4rem; margin-left: auto; }
.foot__links a { font-size: .78rem; text-decoration: none; color: rgba(255, 255, 255, .5); }
.foot__links a:hover { color: #fff; }

/* =============================================================================
   FURNITURE — the last few things, none of which belong to a section
   -----------------------------------------------------------------------------
   THE REVEAL IS GONE. The shell this sheet came from faded elements in on
   scroll, gated on html.js so a browser without the script still got the
   content. A legal page reveals nothing: every word of it is there on load,
   which is the only behaviour a reader citing a clause can rely on. Removing
   the rules removed the only reason this sheet cared about html.js.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    .btn { transition: none; }
}

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }

/* Read, not seen. The pill's lit segment is a span rather than a link, and a
   span carrying only an aria-label is announced by nothing — so it carries its
   words as real text and hides them here instead. */
.vh {
    position: absolute; width: 1px; height: 1px; margin: -1px;
    padding: 0; border: 0; overflow: hidden; white-space: nowrap;
    clip: rect(0 0 0 0); clip-path: inset(50%);
}

/* The skip link. background:var(--ink) + color:#fff, which the dark edition
   has to answer or it is white on white — invisible to every check that only
   looks at what is on screen, and the very first thing a keyboard user
   reaches. */
.skip {
    position: absolute; left: -9999px; top: 0; z-index: 400;
    background: var(--ink); color: #fff; padding: .8rem 1.2rem; text-decoration: none;
}
.skip:focus { left: 0; }

/* Print. The chrome goes and the words stay. The lab goes too: it is a live
   instrument whose whole output is a file you downloaded, and a printed
   screenshot of a control panel helps nobody. */
@media print {
    .nav, .menu, .mode-pill, .skip, .ll-lab, .ll-bar { display: none !important; }
    body { font-size: 11.5pt; }
    .band { padding-block: 1rem; break-inside: auto; }
    .band--tint { background: none; }
    .wrap { max-width: none; padding-inline: 0; }
    h1, h2, h3 { break-after: avoid; }
    .foot { background: none; color: #000; border-top: 1px solid #999; }
}

/* =============================================================================
   THE LOGO LAB
   -----------------------------------------------------------------------------
   Everything below is the instrument. Three prefixes and nothing else:

     .ll-      the lab's own furniture — panels, bars, buttons, fields
     .ll-pill  the LOGOTYPE, a real DOM element styled from the same numbers
               the canvas exporter uses, so the screen and the PNG cannot drift
     .ll-stage the ARTBOARD, whose ground the reader chooses

   THREE RULES THIS BLOCK KEEPS, each of them a house rule that has cost a
   build before:

     1. Every grid track is minmax(0, 1fr). A bare 1fr grows to min-content, and
        one unwrappable row — a 256px pill set in 143px type — then sets the
        width of every other track and of the document.
     2. Anything that can be wider than its column scrolls INSIDE its own box
        (overflow-x: auto). Nothing on this page may widen the document.
     3. Every field is 16px on a coarse pointer and every control clears 44px,
        measured on the control itself rather than on a container it might not
        be in. The old build put the 44px floor on `.lab-actions .btn-sm` and
        half the buttons were not in a `.lab-actions`.
   ========================================================================== */

/* ------------------------------------------------------------------ layout */
.ll-lab {
    display: grid;
    grid-template-columns: 300px minmax(0, 1fr) 300px;
    gap: 1.4rem;
    align-items: start;
}
@media (max-width: 1180px) {
    .ll-lab { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    /* The artboard first: on a narrow window the thing you are looking at must
       not be below two panels of controls. */
    .ll-lab > .ll-stagecol { order: -1; grid-column: 1 / -1; }
}
@media (max-width: 760px) {
    .ll-lab { grid-template-columns: minmax(0, 1fr); }
}

.ll-panel {
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--tint);
    padding: 1rem 1.05rem 1.15rem;
    min-width: 0;
}
.ll-panel + .ll-panel { margin-top: 1.1rem; }
.ll-panel h3 {
    font-size: .70rem; font-weight: 700; letter-spacing: .17em;
    text-transform: uppercase; color: var(--ink-55);
    margin: 0 0 .8rem;
}
.ll-panel h3 + .ll-note { margin-top: -.5rem; }
.ll-note { font-size: .74rem; line-height: 1.5; color: var(--muted); margin: .55rem 0 0; }
.ll-note b { color: var(--ink-77); font-weight: 600; }

/* ------------------------------------------------------------------- bars */
.ll-bar {
    display: flex; flex-wrap: wrap; align-items: center; gap: .55rem .9rem;
    margin: 0 0 1.1rem;
}
.ll-bar__label {
    font-size: .66rem; font-weight: 700; letter-spacing: .16em;
    text-transform: uppercase; color: var(--ink-55);
    flex: 0 0 auto;
}

/* --------------------------------------------------------- segmented sets
   A group of buttons where exactly one is lit. `aria-pressed` is the truth and
   `.is-on` is the paint; both are written together, never one without the
   other. */
/* THE RADIUS IS HALF ONE ROW, NOT 999px. A capsule is only a capsule while the
   box is one row high; the moment the buttons wrap to two or three rows, 999px
   draws a tall stadium whose corners bulge around the text — a blob, and it was
   reported as one. Half the single-row height (34px button + 3px padding twice
   + 1px border = 42) is EXACTLY the capsule on one line and a tidy rounded
   rectangle on two or three. One number, no wrap detection, nothing to keep in
   step with the button count. */
.ll-seg { display: flex; flex-wrap: wrap; gap: 4px; padding: 3px; min-width: 0;
          border: 1px solid var(--line); border-radius: 21px; background: var(--paper); }
.ll-seg__b {
    font: inherit; font-size: .74rem; font-weight: 600; letter-spacing: .02em;
    padding: .42rem .8rem; border-radius: 999px;
    border: 1px solid transparent; background: none; color: var(--ink-77);
    cursor: pointer; white-space: nowrap;
    transition: background .18s var(--ease), color .18s var(--ease);
}
.ll-seg__b:hover { background: var(--line-soft); color: var(--ink); }
.ll-seg__b.is-on { background: var(--ink); color: var(--paper); }
.ll-seg__b[disabled] { opacity: .4; cursor: not-allowed; }

/* ---------------------------------------------------------------- buttons */
.ll-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
    font: inherit; font-size: .78rem; font-weight: 600; letter-spacing: .01em;
    padding: .55rem .9rem; border-radius: 8px;
    border: 1px solid var(--line); background: var(--paper); color: var(--ink);
    text-decoration: none; cursor: pointer; white-space: nowrap;
    transition: background .18s var(--ease), border-color .18s var(--ease),
                color .18s var(--ease);
}
.ll-btn:hover { border-color: var(--ink); }
.ll-btn[disabled] { opacity: .42; cursor: not-allowed; border-color: var(--line); }
.ll-btn--primary { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.ll-btn--primary:hover { background: #000; }
.ll-btn.is-on { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.ll-btn.is-flash { background: var(--accent-fill); color: var(--on-accent); border-color: var(--accent-fill); }
.ll-btn svg { width: 14px; height: 14px; flex: 0 0 auto; }
.ll-btns { display: flex; flex-wrap: wrap; gap: .5rem; }

/* THE 44px FLOOR. On the control itself, gated on the pointer rather than on
   the width, because a coarse pointer on a wide screen still has a finger. */
@media (hover: none) and (pointer: coarse) {
    .ll-btn, .ll-seg__b, .ll-chip, .ll-select, .ll-field { min-height: 44px; }
    .ll-seg__b { padding-inline: 1rem; }
    /* A HEIGHT IS HALF A TARGET. The seed step arrows are one glyph wide and
       measured 35 × 44 — a floor on one axis only is not a 44px control. */
    .ll-btn { min-width: 44px; }
}

/* ----------------------------------------------------------------- fields */
.ll-row { display: flex; align-items: center; gap: .6rem; margin: 0 0 .6rem; min-width: 0; }
.ll-row > label { flex: 0 0 5.6rem; font-size: .76rem; color: var(--ink-77); }
.ll-row > input[type=range] { flex: 1 1 auto; min-width: 0; }
.ll-val { flex: 0 0 2.4rem; text-align: right; font-size: .74rem;
          font-variant-numeric: tabular-nums; color: var(--ink-55); }
.ll-hint { font-size: .72rem; color: var(--muted); }

.ll-field, .ll-select {
    font: inherit; font-size: 16px;      /* never below 16: iOS Safari zooms */
    padding: .5rem .6rem; border-radius: 7px;
    border: 1px solid var(--line); background: var(--paper); color: var(--ink);
    min-width: 0; width: 100%;
}
.ll-select { padding-block: .45rem; }
.ll-field:focus, .ll-select:focus { outline: none; border-color: var(--ink); }
.ll-field::placeholder { color: var(--muted); }
textarea.ll-field { min-height: 76px; resize: vertical; line-height: 1.5; }
.ll-row .ll-field, .ll-row .ll-select { width: auto; flex: 1 1 auto; }
.ll-lbl {
    display: block; font-size: .7rem; font-weight: 700; letter-spacing: .13em;
    text-transform: uppercase; color: var(--ink-55); margin: 0 0 .35rem;
}
.ll-lbl + .ll-field, .ll-lbl + .ll-select { margin-bottom: .8rem; }

input[type=range] { accent-color: var(--accent); height: 22px; }
/* flex: 0 0 auto — a checkbox is a flex item inside .ll-row, and with the
   default flex-shrink it was squeezed BELOW its own declared size by a long
   hint beside it: #c-mono measured 19px at 390 and 16px at 360. */
input[type=checkbox] { accent-color: var(--accent); width: 18px; height: 18px; flex: 0 0 auto; }
@media (hover: none) and (pointer: coarse) {
    input[type=range] { height: 44px; }
    input[type=checkbox] { width: 22px; height: 22px; }
    /* THE BOX IS THE LOOK, THE LABEL IS THE TARGET. A 22px checkbox is the
       right size for a checkbox and the wrong size for a finger, and every one
       of these is `for=`'d to its label — so the label carries the 44, exactly
       the way File Search's switches already do it. */
    .ll-row > label { min-height: 44px; display: flex; align-items: center; }
}

/* ------------------------------------------------------------------ chips */
.ll-chip {
    font: inherit; font-size: .74rem; font-weight: 500;
    padding: .38rem .7rem; border-radius: 999px;
    border: 1px solid var(--line); background: var(--paper); color: var(--ink-77);
    cursor: pointer;
}
.ll-chip:hover { border-color: var(--ink); color: var(--ink); }
.ll-chip.is-on { background: var(--accent-fill); border-color: var(--accent-fill); color: var(--on-accent); }
.ll-chips { display: flex; flex-wrap: wrap; gap: .4rem; }

.ll-qchip {
    font-size: .68rem; font-weight: 600; letter-spacing: .04em;
    padding: .28rem .55rem; border-radius: 999px;
    border: 1px solid var(--line); color: var(--ink-55);
    font-variant-numeric: tabular-nums;
}
.ll-qchips { display: flex; flex-wrap: wrap; gap: .35rem; margin: .7rem 0 0; }

/* =============================================================================
   THE ARTBOARD
   -----------------------------------------------------------------------------
   The ground is the reader's, not the edition's. Five literal grounds, and the
   two that read "page" and "deep" are the only two that follow the edition —
   they are there so a mark can be checked against the site it will sit on.
   ========================================================================== */
.ll-stage {
    position: relative;
    border: 1px solid var(--line);
    border-radius: 12px;
    overflow: hidden;
    display: grid; place-items: center;
    padding: 1.1rem;
    min-width: 0;
}
/* THE FIVE GROUNDS, WRITTEN ONCE.
   They are keyed on [data-ground-target] and not on the class of the box that
   carries them, because there are three such boxes — the artboards, the size
   rungs and the font cards — and the first draft of this sheet wrote the rules
   twice and forgot the third, so every font specimen sat on nothing at all.
   The attribute is also the reason the seg buttons in the control bar, which
   carry data-ground of their own, are not painted by these rules. */
[data-ground-target][data-ground="white"] { background: #FFFFFF; }
[data-ground-target][data-ground="black"] { background: #000000; }
[data-ground-target][data-ground="page"]  { background: var(--paper); box-shadow: inset 0 0 0 1px var(--line-soft); }
[data-ground-target][data-ground="deep"]  { background: var(--deep); }
/* THE CHECKERBOARD. Two 45° gradients at 20px, offset by half a tile, is the
   standard "this is transparent" pattern and it is drawn rather than fetched.
   It is the same grey in both editions on purpose: a checker that changed with
   the page would read as a colour choice instead of as an absence. */
[data-ground-target][data-ground="clear"] {
    background-color: #FFFFFF;
    background-image:
        linear-gradient(45deg, #D9DEE3 25%, transparent 25%, transparent 75%, #D9DEE3 75%),
        linear-gradient(45deg, #D9DEE3 25%, transparent 25%, transparent 75%, #D9DEE3 75%);
    background-size: 20px 20px;
    background-position: 0 0, 10px 10px;
}
.ll-stage canvas { display: block; max-width: 100%; height: auto; }
.ll-stage__cap {
    position: absolute; left: 0; right: 0; bottom: 0;
    padding: .4rem .7rem;
    font-size: .66rem; letter-spacing: .06em;
    background: rgba(30, 38, 43, .72); color: #fff;
    font-variant-numeric: tabular-nums;
    /* One line, and it must not widen the stage. */
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ll-stagecol { min-width: 0; }
.ll-stagecol > * + * { margin-top: .85rem; }

/* ------------------------------------------------------------ contact sheet
   Three across at every width. Nine cells is the whole idea of a contact
   sheet; folding it to two columns turns it into a list. Each cell is square
   by ratio rather than by a fixed pixel size, and clips its own overflow so a
   canvas inside it can never set the track width. */
.ll-sheet {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .5rem;
}
.ll-cell {
    position: relative; aspect-ratio: 1 / 1;
    padding: 0; overflow: hidden; min-width: 0;
    border: 1px solid var(--line); border-radius: 9px;
    background: none; cursor: pointer;
    transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.ll-cell canvas { display: block; width: 100%; height: 100%; }
.ll-cell:hover { border-color: var(--ink); }
.ll-cell.is-adopted { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-fill); }
.ll-cell.is-next    { border-color: var(--accent); }
.ll-cell__seed {
    position: absolute; left: 4px; bottom: 4px;
    font-size: .62rem; font-variant-numeric: tabular-nums;
    padding: 1px 5px; border-radius: 4px;
    background: rgba(30, 38, 43, .72); color: #fff;
}
.ll-sheet__head { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .8rem; }
.ll-sheet__head > .ll-hint { flex: 1 1 12rem; min-width: 0; }
.ll-auto { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.ll-live { font-size: .72rem; color: var(--muted); min-height: 1.2em; }

/* ------------------------------------------------------------- size ladder */
.ll-ladder { display: flex; flex-wrap: wrap; gap: .55rem; align-items: flex-end; }
.ll-rung { display: flex; flex-direction: column; align-items: center; gap: .3rem; }
.ll-rung canvas { display: block; border: 1px solid var(--line-soft); border-radius: 3px; }
.ll-rung span { font-size: .6rem; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------- the context */
.ll-ctx { display: flex; flex-wrap: wrap; gap: .8rem; }
.ll-ctx__cell { display: flex; flex-direction: column; align-items: center; gap: .3rem; }
.ll-ctx__cell canvas { display: block; border-radius: 6px; border: 1px solid var(--line-soft); }
.ll-ctx__cell canvas.is-round { border-radius: 50%; }
.ll-ctx__cell span { font-size: .6rem; color: var(--muted); letter-spacing: .06em; text-transform: uppercase; }
.ll-tab {
    display: flex; align-items: center; gap: .35rem;
    padding: .3rem .5rem; border-radius: 6px 6px 0 0;
    border: 1px solid var(--line); border-bottom: 0; background: var(--tint);
    font-size: .62rem; color: var(--ink-55); max-width: 140px;
    overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.ll-tab canvas { border: 0; flex: 0 0 auto; }

/* ---------------------------------------------------------------- history */
.ll-hist { display: flex; flex-direction: column; gap: .4rem; max-height: 320px;
           overflow-y: auto; overscroll-behavior: contain; }
.ll-hist__item {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    gap: .55rem; align-items: center;
    padding: .4rem; border: 1px solid var(--line); border-radius: 8px;
    background: var(--paper); text-align: left;
}
/* A BUTTON WITH display: contents HAS NO BOX. It measured 0 x 0: clicks still
   reached it by bubbling from the canvas, but it could carry no focus ring —
   so the one keyboard user on this list had no way to see what was selected —
   and display:contents on a button is dropped from the accessibility tree in
   some engines. It is a real box now, laid out as the row it was pretending
   to be. */
.ll-hist__open {
    display: flex; align-items: center; gap: .55rem; min-width: 0;
    font: inherit; text-align: left; padding: 0; color: inherit;
    background: none; border: 0; cursor: pointer;
}
.ll-hist__open canvas { flex: 0 0 auto; }
.ll-hist__open:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 7px; }
.ll-hist__item canvas { display: block; border-radius: 5px; }
.ll-hist__meta { min-width: 0; }
.ll-hist__meta b { display: block; font-size: .78rem; font-weight: 600; color: var(--ink);
                   overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ll-hist__meta span { display: block; font-size: .66rem; color: var(--muted);
                      font-variant-numeric: tabular-nums;
                      overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ll-pick {
    width: 26px; height: 26px; flex: 0 0 auto; padding: 0;
    border: 1px solid var(--line); border-radius: 6px; background: var(--paper);
    cursor: pointer; color: var(--ink);
}
.ll-pick[aria-pressed="true"] { background: var(--accent-fill); border-color: var(--accent-fill); color: var(--on-accent); }
@media (hover: none) and (pointer: coarse) { .ll-pick { width: 44px; height: 44px; } }
.ll-empty { font-size: .76rem; color: var(--muted); padding: .5rem 0; }

/* --------------------------------------------------------------- compare */
.ll-overlay {
    position: fixed; inset: 0; z-index: 200;
    background: rgba(12, 17, 22, .72);
    display: grid; place-items: center; padding: 1rem;
}
.ll-overlay__panel {
    background: var(--paper); border-radius: 14px; border: 1px solid var(--line);
    /* WIDTH, NOT max-width. .ll-overlay is `place-items: center`, which sets
       justify-items: center — so the panel was laid out under a max-content
       constraint and max-width never engaged. Under max-content the
       repeat(auto-fit,…) below resolves to exactly ONE repetition, so the
       dialog whose heading reads "Side by side" was a single 332px column at
       every viewport, desktop included. */
    width: min(960px, 100%); max-height: 88vh; overflow: auto;
    padding: 1.1rem;
}
.ll-overlay__head { display: flex; align-items: center; gap: 1rem; margin-bottom: .9rem; }
.ll-overlay__head strong { font-size: .82rem; font-weight: 600; }
.ll-overlay__head .ll-btn { margin-left: auto; }
.ll-cmp { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: 1rem; }
.ll-cmp__slot { display: flex; flex-direction: column; align-items: center; gap: .4rem; min-width: 0; }
.ll-cmp__slot canvas { display: block; max-width: 100%; height: auto; border-radius: 8px; }
.ll-cmp__slot p { margin: 0; font-size: .68rem; color: var(--muted); text-align: center; }

/* =============================================================================
   THE LOGOTYPE
   -----------------------------------------------------------------------------
   One spec object per rung — height, font size, side padding, radius, tracking
   — and TWO consumers: this DOM pill, styled from custom properties, and the
   canvas exporter. They read the same numbers, so the caption, the specimen
   and the PNG cannot disagree. In the build this replaces they disagreed three
   ways: the specimen was 0.5px tighter than the caption in 22 of 24 fonts, and
   the exporter ignored the rung entirely and re-derived a shape from a fixed
   1.62 ratio.
   ========================================================================== */
.ll-pill {
    display: inline-flex; align-items: center; justify-content: center;
    box-sizing: border-box;
    height: var(--p-h);
    padding-inline: var(--p-pad);
    border-radius: var(--p-r);
    font-family: var(--p-family);
    font-size: var(--p-size);
    font-weight: var(--p-weight);
    letter-spacing: var(--p-track);
    line-height: 1;
    white-space: nowrap;
    user-select: all;
}
/* THE TRAILING LETTER-SPACE. letter-spacing puts a gap after the LAST glyph as
   well, and that gap is inside the inline box's width — so centring the box
   leaves the visible word half a tracking-unit left of centre. A negative
   right margin of exactly one unit takes it back out of the measurement, which
   is the same subtraction the canvas exporter does in pixels. An indent would
   not do: it widens the box that the centring then re-centres. */
.ll-pill__t { margin-right: calc(var(--p-track) * -1); }
.ll-pill--brand   { background: linear-gradient(135deg, #FF6B00 0%, #EA580C 100%); color: #000000; }
/* Mono overrides the gradient with a flat plate. Written as a var with the
   gradient as its own fallback so one declaration serves both states. */
.ll-pill--brand[style*="--p-fill"] { background: var(--p-fill); color: var(--p-type); }
.ll-pill--knock   { background: var(--p-ink); color: var(--p-ground); }
.ll-pill--outline { background: none; color: var(--p-ink); box-shadow: inset 0 0 0 var(--p-line) var(--p-ink); }
.ll-pill--plain   { background: none; color: var(--p-ink); padding-inline: 0; }
/* Knockout on a clear ground: the letters are holes, and on screen they show
   the same checker the artboard shows, because in the exported PNG they are
   genuinely transparent. */
.ll-pill--knock.is-clear {
    color: transparent;
    background-image:
        linear-gradient(45deg, #D9DEE3 25%, transparent 25%, transparent 75%, #D9DEE3 75%),
        linear-gradient(45deg, #D9DEE3 25%, transparent 25%, transparent 75%, #D9DEE3 75%);
    background-size: 20px 20px;
    background-position: 0 0, 10px 10px;
    background-color: #FFFFFF;
}
.ll-pill--knock.is-clear .ll-pill__t {
    -webkit-background-clip: text; background-clip: text; color: transparent;
    background-image:
        linear-gradient(45deg, #D9DEE3 25%, transparent 25%, transparent 75%, #D9DEE3 75%),
        linear-gradient(45deg, #D9DEE3 25%, transparent 25%, transparent 75%, #D9DEE3 75%);
    background-size: 20px 20px; background-position: 0 0, 10px 10px;
    background-color: #FFFFFF;
}
.ll-pill--knock.is-clear { background: var(--p-ink); }

/* The rung: caption, then the specimen in a box that scrolls rather than
   pushing the page. A 256px pill set in 143px type is 700px wide with a short
   word and 1400px with a long one; NOTHING may let that reach the document. */
.ll-size { border-top: 1px solid var(--line-soft); padding: .9rem 0; min-width: 0; }
.ll-size:first-child { border-top: 0; }
.ll-size__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: .4rem .8rem; margin-bottom: .55rem; }
.ll-size__name { font-size: .78rem; font-weight: 600; color: var(--ink); }
.ll-size__spec { font-size: .66rem; color: var(--muted); font-variant-numeric: tabular-nums;
                 letter-spacing: .03em; }
.ll-size__head .ll-btns { margin-left: auto; }
.ll-size__box {
    overflow-x: auto; overflow-y: hidden;
    padding: .7rem;
    border-radius: 10px;
    -webkit-overflow-scrolling: touch;
}
/* The rung box takes its ground from the [data-ground-target] rules above. */

/* ------------------------------------------------------------- font cards */
.ll-fonts {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
    gap: .8rem;
}
.ll-font {
    display: flex; flex-direction: column; gap: .55rem;
    padding: .8rem; min-width: 0;
    border: 1px solid var(--line); border-radius: 11px;
    background: var(--paper); color: inherit; text-align: left;
    font: inherit; cursor: pointer;
    transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.ll-font:hover { border-color: var(--ink); }
.ll-font[aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-fill); }
.ll-font__box { overflow-x: auto; overflow-y: hidden; border-radius: 8px; padding: .5rem; }
.ll-font__name { font-size: .76rem; font-weight: 600; color: var(--ink); }
.ll-font__spec { font-size: .64rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.ll-font__warn { font-size: .62rem; color: var(--unsure); }

/* --------------------------------------------------------------- the lockup */
.ll-lock { display: flex; flex-wrap: wrap; gap: 1.2rem; align-items: flex-start; }
.ll-lock > .ll-stage { flex: 1 1 min(420px, 100%); min-width: 0; }
.ll-lock > .ll-panel { flex: 1 1 min(280px, 100%); min-width: 0; }

/* ------------------------------------------------------------ the contact */
.ll-form { display: grid; gap: .8rem; max-width: 34rem; }
.ll-form__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.ll-status { font-size: .8rem; margin: 0; min-height: 1.4em; }
.ll-status[data-state="ok"]   { color: var(--free); }
.ll-status[data-state="bad"]  { color: var(--taken); }
.ll-status[data-state="work"] { color: var(--ink-55); }

/* ------------------------------------------------------------------- table */
.ll-tablewrap { overflow-x: auto; margin-top: 1rem; }
.ll-table { border-collapse: collapse; font-size: .78rem; min-width: 32rem; }
.ll-table th, .ll-table td { text-align: left; padding: .42rem .8rem .42rem 0;
                             border-bottom: 1px solid var(--line-soft);
                             font-variant-numeric: tabular-nums; }
.ll-table th { font-size: .64rem; letter-spacing: .13em; text-transform: uppercase;
               color: var(--ink-55); font-weight: 700; }

/* ------------------------------------------------------------------- misc */
.ll-kbd { font-size: .66rem; color: var(--muted); }
.ll-kbd kbd {
    font: inherit; font-size: .62rem; padding: 1px 5px; border-radius: 4px;
    border: 1px solid var(--line); background: var(--tint); color: var(--ink-77);
}
.ll-facts { display: flex; flex-wrap: wrap; gap: .4rem 1.6rem; margin: 2.4rem 0 0;
            padding-top: 1.5rem; border-top: 1px solid var(--line); }
.ll-fact { font-size: .72rem; font-weight: 700; letter-spacing: .13em;
           text-transform: uppercase; color: var(--ink-55); }
.ll-fact b { color: var(--ink); font-size: .95rem; font-weight: 700; letter-spacing: .02em; }
.ll-details { border: 1px solid var(--line); border-radius: 10px; padding: 0 .9rem; margin-top: .9rem; }
.ll-details > summary {
    cursor: pointer; padding: .7rem 0; list-style: none;
    font-size: .7rem; font-weight: 700; letter-spacing: .14em;
    text-transform: uppercase; color: var(--ink-55);
}
.ll-details > summary::-webkit-details-marker { display: none; }
.ll-details > summary::after { content: ' +'; }
.ll-details[open] > summary::after { content: ' \2212'; }
.ll-details > *:last-child { padding-bottom: .9rem; }
@media (hover: none) and (pointer: coarse) { .ll-details > summary { padding-block: 1rem; } }

@media (prefers-reduced-motion: reduce) {
    .ll-btn, .ll-seg__b, .ll-font, .ll-cell { transition: none; }
}

/* -----------------------------------------------------------------------------
   [hidden] IS A USER-AGENT DECLARATION AND LOSES TO ANY AUTHOR display RULE.
   Three controls on this page are hidden by script and every one of them had an
   author display: the monogram letters row (flex), the resume button
   (inline-flex) and the reference-image strip's buttons. Without these lines
   `el.hidden = true` sets an attribute and changes nothing on screen — which is
   exactly the failure that is hardest to spot, because the code looks right.
   -------------------------------------------------------------------------- */
.ll-row[hidden],
.ll-btn[hidden],
.ll-seg__b[hidden],
.ll-chip[hidden],
.ll-btns[hidden],
.ll-note[hidden] { display: none !important; }

/* The mono pair sits inside a row that already carries Finish and Corner, so it
   is drawn tighter than a first-class segment — it is a modifier to the finish,
   not a fourth axis competing with it. */
.ll-seg--tight .ll-seg__b { padding-inline: .55rem; font-size: .72rem; }

/* The sheet's own close control. Quieter than "Nine more" beside it — that is
   the action, this is the exit — and pushed to the end of the header row so it
   sits where a close always sits. */
.ll-btn--x { margin-left: auto; background: none; border-color: var(--line);
             color: var(--ink-55); }
.ll-btn--x:hover { color: var(--ink); border-color: var(--ink); background: none; }
