@import url('../marketing.css');

/* =====================================================================
 * Typeface — SSHOW SEO Sans, the specimen
 *
 * The font's own release site, set on the s.show stage. Its sections,
 * components and interactions stay; its header, theme switch, downloads
 * and colors give way to the site's header and footer, the stage tokens
 * and the night stage in dark. The face sets the specimen surfaces
 * (.tf-face, always with lang="en"): the name, the manifesto, glyphs,
 * testers and artwork. Every word around them keeps the site's own type,
 * as on every other page.
 *
 * It shares /design's details: chapters open on a meta row under the
 * stage's eyebrow, values and spec labels are set small in the site's
 * own face with tabular figures (the stage pages set no monospace
 * anywhere), specimens stand on raised paper (the stages on the editor's
 * dotted canvas), the editor's selection keeps its blue, and the night
 * is the one dark. No crosshair or crop marks: the tools are the panels
 * themselves, as on /design.
 * No glow, no aura: the page is ink and paper, and nothing here is
 * colored but the photos and the artwork.
 *
 * Section heads cut in like scenes (.mt-section-inner); tools, sticky
 * and measured things stand outside the cut so they never fade while
 * used. Every hidden start state is a keyframe `from` or armed by
 * typeface.js, so without script the whole page simply shows. The
 * shared stage (tokens, blank page, type, scene rhythm) comes from
 * marketing.css; this sheet holds the page, in page order, then the
 * responsive, dark, reduced-motion and forced-colors blocks.
 * ===================================================================== */

#mt-page.tf-page {
    /* The DI buttons ease on --di-ease, which no shared sheet defines. */
    --di-ease: var(--mt-ease);
    --di-ease-spring: var(--mt-ease-spring);

    /* The face, falling back to the site's own stack (and Hangul always
       does: the face's unicode-range stops at Latin). */
    --tf-face: var(--global-font-title);
    /* Values and spec labels: the site's own face with tabular figures,
       as on /design (--ds-mono) — the stage pages set no monospace
       anywhere. */
    --tf-mono: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", sans-serif;

    /* A card is the page itself with a hairline; its artwork sits on the
       raised paper inside it, as on the font site. */
    --tf-card: var(--mt-bg);
    --tf-art: var(--mt-bg-raise);
    /* Corners, as /about's and /design's stages: a tool panel or a
       full-width card 28px (24 at the content fold, 20 on a phone), a tile
       24px (20 on a phone). Paper inset in one is rounded to match. */
    --tf-r: 28px;
    --tf-r-tile: 24px;
    /* The editor's canvas: a faint dot every 22px, inside stages only. */
    --tf-dot: rgba(var(--mt-ink-rgb), 0.075);
    /* Surfaces lift only under a pointer, a soft shadow and no light. */
    --tf-lift: 0 24px 48px -32px rgba(22, 26, 44, 0.35);
    /* The marquee's band: the night on the lit stage, a raised night at
       night (the night panel of /design). */
    --tf-band: var(--tf-night);
    --tf-band-ink: var(--tf-night-ink);
    /* The page turned over (the night tiles, the tester's invert): the
       night under light type on the lit stage, paper under ink at night. */
    --tf-inverse: var(--tf-night);
    --tf-inverse-ink: var(--tf-night-ink);
    --tf-inverse-ink-rgb: var(--tf-night-ink-rgb);
    /* The selection blue that reads on that turned-over ground. */
    --tf-inverse-sel: #3B7DE0;
    /* A spec tag's ground: the deeper selection blue in both themes, so
       its small white figures keep 6:1 (as on /design). */
    --tf-tag: #185CC2;

    /* Artwork that keeps its own colors in both themes: the night slide
       and the phone (the founder's night), the poster's warm paper, and
       the slide as projected light, its black lifted to a lit screen's
       grey. */
    --tf-night: #121318;
    --tf-night-rgb: 18, 19, 24;
    --tf-night-raise: #1B1C22;
    --tf-night-ink: #EDEFF5;
    --tf-night-ink-rgb: 237, 239, 245;
    --tf-night-ink-2: #A7AEC0;
    --tf-poster: #F1EFEC;
    --tf-poster-ink: #16171B;
    --tf-poster-ink-rgb: 22, 23, 27;
    --tf-projected: #20232C;
    --tf-projected-rgb: 32, 35, 44;
    /* The hall photo's own dusk, under it until it loads. */
    --tf-hall-ground: #1D1A17;
}

/* Frozen under the glyph sheet, where it stands (typeface.js 6). */
html.tf-locked { overflow: clip; }

/* Controls that need typeface.js stay out of sight until it has wired
   them (is-tf-ready): without script the page still reads, and nothing
   on it pretends to work. */
#mt-page.tf-page:not(.is-tf-ready) [data-tf-needs-js] { display: none; }
/* What is content as well as a control stays: the nine weights and the
   glyph cells are disabled in the markup until the script wires them
   (as /design's swatches are), and the glyph above the weights is no
   handle yet. Their hover answers only once they work (below). */
.tf-wrow:disabled,
.tf-cell:disabled { cursor: default; }
#mt-page.tf-page:not(.is-tf-ready) .tf-scrub-glyph { cursor: auto; }

/* The fixed header never covers what the page scrolls to, as on /design:
   the chapters the hero's two ways in jump to, and focused controls
   (Shift+Tab included) land below it. The scroller keeps the header's
   room; an announcement's height is known only inside <body>, so the
   targets add it, and a little air. */
html:has(#mt-page.tf-page) { scroll-padding-top: calc(var(--header-height) + 16px); }
#mt-page.tf-page .mt-section,
#mt-page.tf-page :is(a[href], button, input, [tabindex], [contenteditable]) { scroll-margin-top: calc(var(--announcement-h, 0px) + 8px); }

/* Words that never break: the name, wherever it stands in a sentence. */
.tf-nb { white-space: nowrap; }

/* The face, on specimen surfaces. Its own tracking is built in, so every
   size runs at 0. */
.tf-face { font-family: var(--tf-face); font-synthesis: none; font-kerning: normal; letter-spacing: 0; }

/* An OpenType feature, switched on for one specimen. */
.tf-feat-case { font-feature-settings: 'case'; }
.tf-feat-tnum { font-feature-settings: 'tnum'; }
.tf-feat-ss01 { font-feature-settings: 'ss01'; }
.tf-feat-ss02 { font-feature-settings: 'ss02'; }

/* A chapter's meta row, the spec sheet's header (as on /design's .ds-meta):
   a hairline across, and under it the number and topic as the stage's
   own eyebrow (.mt-eyebrow, in both languages), alone. */
.tf-meta {
    margin-bottom: clamp(32px, 4vw, 56px);
    padding-top: 14px;
    border-top: 1px solid var(--mt-hair-2);
    font-size: 13px;
    line-height: 1.4;
}
.tf-meta-topic.mt-eyebrow { display: block; margin: 0; line-height: 1.4; overflow-wrap: break-word; }

/* Values and spec labels: small, tabular, in the third ink, and in the
   second on raised paper, where the third falls short of 4.5:1. Latin
   labels in capitals, tracked a little, as a spec sheet sets them. */
.tf-num,
.tf-pr-num,
.tf-art-label {
    font-family: var(--tf-mono);
    font-size: 11px;
    font-weight: 500;
    line-height: 1.4;
    letter-spacing: 0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--mt-ink-3);
}
.tf-pr-num,
.tf-art-label { color: var(--mt-ink-2); }
.tf-art-label:lang(en) { text-transform: uppercase; letter-spacing: 0.08em; }
.tf-num,
.tf-pr-num { font-size: 12px; }
/* Korean in a label keeps its own spacing: the tracking is for Latin
   (the eyebrows keep the stage's own, as everywhere on the site). */
.tf-page :is(.tf-stat dt, .tf-quote-label, .tf-tenet-label, .tf-pr-facts dt, .tf-proof span, .tf-facts dt, .tf-insp-labels span, .tf-insp-meta :is(dt, dd), .tf-axis-m small, .tf-chip-label, .tf-b-cap):lang(ko) { letter-spacing: 0; }
/* Labels keep their words whole: they wrap only between words, unless a
   single word could not fit at all (#mt-page lets anything break). */
.tf-page :is(.tf-stat dt, .tf-proof span, .tf-ctl label, .tf-ctl output, .tf-facts dt, .tf-pr-facts dt) { overflow-wrap: break-word; }

/* The editor's canvas inside a stage: a faint dot every 22px, centered so
   the grid sits even on both sides of the specimen. */
.tf-canvas {
    background-image: radial-gradient(var(--tf-dot) 1px, transparent 1.4px);
    background-size: 22px 22px;
    background-position: center;
}

/* A spec tag, the editor's: white tabular figures on its selection blue. */
.tf-page .tf-tag {
    font-family: var(--tf-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.02em;
    font-variant-numeric: tabular-nums;
    background: var(--tf-tag);
}
.tf-tag:not(.mt-select-tag) {
    padding: 3px 7px;
    border-radius: 4px;
    color: #fff;
    line-height: 1.2;
    white-space: nowrap;
}

/* A link back (to /design): its arrow leads and leans back on hover. */
.tf-back { display: inline-flex; align-items: center; gap: 6px; }

/* Cards and panels: the page with a hairline, rounded as /design's
   stages (the panels and the full-width cards) and tiles (the rest). A
   card lifts only under a pointer (below); a panel is a tool and stays
   flat. Neither clips: what inside must be round is rounded itself. */
.tf-card { position: relative; border-radius: var(--tf-r-tile); background: var(--tf-card); box-shadow: inset 0 0 0 1px var(--mt-hair); }
.tf-card:is(.tf-pr, .tf-mk) { border-radius: var(--tf-r); }
.tf-panel {
    position: relative;
    border-radius: var(--tf-r);
    background: var(--tf-card);
    box-shadow: inset 0 0 0 1px var(--mt-hair);
}

/* Specimens in font units: the text on y = 0 at 1000 units to the em,
   hairline guides at the face's own metrics (drawn in the markup). */
.tf-svg { display: block; width: 100%; height: auto; overflow: visible; letter-spacing: 0; }
.tf-svg text { font-family: var(--tf-face); font-synthesis: none; font-kerning: normal; fill: currentColor; }
.tf-guide { stroke: currentColor; stroke-width: 1; vector-effect: non-scaling-stroke; opacity: 0.22; }
.tf-guide.is-base { opacity: 0.45; }
.tf-guide.is-axis { stroke-dasharray: 4 5; opacity: 0.4; }

/* Chips: presets (one checked) and features (each pressed), set in ink.
   On touch the hit area grows to 44px without changing the row. */
.tf-chip-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.tf-chip-label { margin-right: 4px; font-size: 12px; font-weight: 500; letter-spacing: 0.02em; color: var(--mt-ink-3); }
.tf-chip {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 34px;
    padding: 0 14px;
    border-radius: 999px;
    box-shadow: inset 0 0 0 1px var(--mt-hair-2);
    font-size: 13px;
    font-weight: 500;
    line-height: 1;
    color: var(--mt-ink-2);
    white-space: nowrap;
    transition: color 0.18s var(--mt-ease), background-color 0.18s var(--mt-ease), box-shadow 0.18s var(--mt-ease), transform 0.3s var(--mt-ease-spring);
}
.tf-chip[hidden] { display: none; }
.tf-chip:is([aria-pressed="true"], [aria-checked="true"]) { background: var(--mt-ink); box-shadow: none; color: var(--mt-bg); }
.tf-chip:focus-visible { outline-offset: 2px; border-radius: 999px; }
.tf-chip.is-feat b { font-weight: 700; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; }

/* Sliders: a hairline track filled in ink to the thumb (--fill, from
   typeface.js), a paper thumb ringed in ink. */
.tf-range {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    width: 100%;
    height: 28px;
    margin: 0;
    background: transparent;
    cursor: pointer;
}
.tf-range::-webkit-slider-runnable-track {
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(var(--mt-ink), var(--mt-ink)) 0 / var(--fill, 50%) 100% no-repeat, var(--mt-hair-2);
}
.tf-range::-moz-range-track { height: 2px; border-radius: 2px; background: var(--mt-hair-2); }
.tf-range::-moz-range-progress { height: 2px; border-radius: 2px; background: var(--mt-ink); }
.tf-range::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    margin-top: -8px;
    border: 1.5px solid var(--mt-ink);
    border-radius: 50%;
    background: var(--mt-bg);
    box-shadow: 0 2px 6px rgba(var(--mt-ink-rgb), 0.18);
    transition: transform 0.3s var(--mt-ease-spring);
}
.tf-range::-moz-range-thumb { width: 16px; height: 16px; border: 1.5px solid var(--mt-ink); border-radius: 50%; background: var(--mt-bg); }
.tf-range:active::-webkit-slider-thumb { transform: scale(1.15); }
.tf-range:focus-visible { outline: none; }
.tf-range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--state-active-bg), 0 0 0 6px var(--focus-outline-color); }
.tf-range:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 4px var(--state-active-bg), 0 0 0 6px var(--focus-outline-color); }

/* Round icon buttons (inspector: close, previous, next). */
.tf-icon-btn {
    display: inline-grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border-radius: 999px;
    box-shadow: inset 0 0 0 1px var(--mt-hair-2);
    color: var(--mt-ink);
    transition: background-color 0.18s var(--mt-ease), box-shadow 0.18s var(--mt-ease);
}
.tf-icon-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.tf-icon-btn:focus-visible { border-radius: 999px; }


/* =====================================================================
 * Hero — the name breathing through its weights, on a specimen sheet
 *
 * Twelve faint columns behind, the name across the whole width on its
 * cap, x-height and baseline hairlines (their values in the margin, a
 * ruler), the tagline directly beneath it, the lede and the two ways in
 * beside it, and the numbers along the floor. A narrow crest of weight
 * ripples through the name twice, then the name rests at Regular; its
 * silhouette holds throughout (the face keeps its width at every
 * weight). No light behind: the type is the picture. The crest holds
 * under the pause button and off screen; without script and under
 * reduced motion the name simply stands at Regular. The words rise in
 * once; nothing here waits for script.
 * ===================================================================== */
.tf-hero {
    position: relative;
    isolation: isolate;
    display: flex;
    min-height: clamp(660px, 92svh, 900px);
    padding: calc(var(--header-height) + clamp(10px, 2vh, 24px)) 0 clamp(36px, 6vh, 64px);
    overflow: clip;
}
/* The sheet's columns, fading out at the top and the bottom. */
.tf-hero::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image: linear-gradient(to right, var(--mt-hair) 1px, transparent 1px);
    background-size: calc((min(100vw, var(--content-wide) + var(--section-pad-x) * 2) - var(--section-pad-x) * 2) / 12) 100%;
    background-position: center top;
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 70%, transparent);
    mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 70%, transparent);
    opacity: 0.7;
    pointer-events: none;
}

.tf-hero-inner { display: flex; flex-direction: column; container-type: inline-size; }
.tf-hero-top { display: flex; align-items: center; justify-content: space-between; gap: 16px; animation: tf-rise 1.3s var(--mt-ease-spring) both; }
.tf-hero-top .tf-back { margin-left: -6px; font-size: 14px; }

/* The motion switch: a quiet pill; on a phone, its icon alone. */
.tf-motion {
    display: inline-flex;
    flex: none;
    align-items: center;
    gap: 8px;
    height: 32px;
    padding: 0 12px 0 10px;
    border-radius: 999px;
    background: var(--header-background-color);
    box-shadow: inset 0 0 0 1px var(--mt-hair-2);
    font-size: 12px;
    font-weight: 500;
    color: var(--mt-ink-2);
    transition: color 0.18s var(--mt-ease), box-shadow 0.18s var(--mt-ease);
}
.tf-motion svg { width: 14px; height: 14px; fill: currentColor; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.tf-motion .tf-i-pause { fill: none; }
.tf-motion .tf-i-play,
html.tf-paused .tf-motion .tf-i-pause { display: none; }
html.tf-paused .tf-motion .tf-i-play { display: block; }
.tf-motion:focus-visible { border-radius: 999px; }

/* On a phone the eyebrow takes two lines: balanced, so the version never
   stands alone. */
.tf-hero-eyebrow { margin: clamp(32px, 7vh, 72px) 0 0; line-height: 1.4; text-wrap: balance; animation: tf-rise 1.3s var(--mt-ease-spring) 0.05s both; }

/* The name. One line across the width (≈ 8.5 em at every weight), each
   letter its own span for the crest. The hairlines are the line box's
   own metrics: half-leading plus the ascent puts the baseline, and the
   cap and x lines stand above it at the face's heights (--tf-*, from
   the font's data on #mt-page). Its box is sized here, by its lines and
   not by its letters, and contained, so a weight change lays out the
   name alone; the letters never reach past it at any weight. */
.tf-name-box { position: relative; margin-top: clamp(14px, 2.4vh, 26px); }
/* The ruler: the hairlines' values in the margin beside the name's first
   line (cap height, x-height, baseline, in font units), each on its line
   with a short tick. Only where the margin is wide enough. */
.tf-ruler {
    position: absolute;
    left: calc(100% + 10px);
    top: 0;
    display: none;
    width: 40px;
    height: calc(100cqw / 8.6 * 0.94);
    font-family: var(--tf-mono);
    font-size: 10px;
    line-height: 1;
    letter-spacing: 0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--mt-ink-3);
    animation: tf-rise 1.3s var(--mt-ease-spring) 0.3s both;
}
.tf-ruler i { position: absolute; left: 0; top: var(--at); display: flex; align-items: center; gap: 4px; font-style: normal; transform: translateY(-50%); }
.tf-ruler i::before { content: ''; width: 6px; height: 1px; background: var(--mt-hair-2); }
.tf-name {
    --lh: 0.94;
    --tf-lines: 1;
    --tf-base: calc((var(--lh) - var(--tf-asc) - var(--tf-dsc)) * 0.5em + var(--tf-asc) * 1em);
    --tf-capl: calc(var(--tf-base) - var(--tf-cap) * 1em);
    --tf-xl: calc(var(--tf-base) - var(--tf-xh) * 1em);
    height: calc(var(--lh) * var(--tf-lines) * 1em);
    contain: size layout paint;
    font-size: calc(100cqw / 8.6);
    font-weight: 400;
    line-height: var(--lh);
    letter-spacing: 0;
    white-space: nowrap;
    background-image:
        linear-gradient(to bottom, transparent calc(var(--tf-capl) - 0.5px), var(--mt-hair-2) calc(var(--tf-capl) - 0.5px), var(--mt-hair-2) calc(var(--tf-capl) + 0.5px), transparent calc(var(--tf-capl) + 0.5px)),
        linear-gradient(to bottom, transparent calc(var(--tf-xl) - 0.5px), var(--mt-hair) calc(var(--tf-xl) - 0.5px), var(--mt-hair) calc(var(--tf-xl) + 0.5px), transparent calc(var(--tf-xl) + 0.5px)),
        linear-gradient(to bottom, transparent calc(var(--tf-base) - 0.5px), var(--mt-hair-2) calc(var(--tf-base) - 0.5px), var(--mt-hair-2) calc(var(--tf-base) + 0.5px), transparent calc(var(--tf-base) + 0.5px));
    background-size: 100% calc(var(--lh) * 1em);
    background-repeat: repeat-y;
    animation: tf-rise 1.3s var(--mt-ease-spring) 0.15s both;
}
.tf-w { display: inline; }
/* The crest: typeface.js breathes each letter 300 ↔ 900, a little
   behind the one before it, twice, then lets the name rest at Regular;
   a pointer can take the whole name to one weight. It writes each
   letter's weight to --lw (is-driven), so without script nothing moves. */
.tf-name.is-driven .tf-l { font-weight: var(--lw, 400); }

.tf-hero-sub {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(24px, 4vw, 64px);
    align-items: start;
    margin-top: clamp(16px, 2.4vh, 26px);
    animation: tf-rise 1.3s var(--mt-ease-spring) 0.4s both;
}
/* The tagline directly beneath the name: plain, one size, one weight. */
.tf-tagline { font-size: clamp(22px, 2.6vw, 34px); font-weight: 400; line-height: 1.2; letter-spacing: 0; color: var(--mt-ink); }
.tf-tagline-ko { margin-top: 10px; font-size: clamp(14px, 1.3vw, 16px); font-weight: 400; line-height: 1.5; letter-spacing: 0; color: var(--mt-ink-3); }
.tf-hero-copy { justify-self: end; max-width: 460px; }
.tf-hero-copy .mt-lede { font-size: clamp(15px, 1.3vw, 17px); }
.tf-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 24px; }

/* The numbers along the floor of the sheet. Values in the face, labels
   in the site's type. */
/* Values share one line; a label that wraps hangs below its value. */
.tf-stats {
    display: grid;
    grid-template-columns: repeat(5, auto);
    justify-content: space-between;
    align-items: start;
    gap: 20px 32px;
    margin: auto 0 0;
    padding-top: 22px;
    border-top: 1px solid var(--mt-hair-2);
    animation: tf-rise 1.3s var(--mt-ease-spring) 0.65s both;
}
/* The floor keeps its distance even when the sheet is short. */
.tf-hero-sub { margin-bottom: clamp(40px, 8vh, 96px); }
.tf-stat { display: flex; flex-direction: column-reverse; justify-content: flex-end; gap: 8px; }
.tf-stat dd { margin: 0; font-size: clamp(24px, 2.7vw, 40px); font-weight: 700; line-height: 1; letter-spacing: 0; white-space: nowrap; }
.tf-stat dt { max-width: 22ch; font-family: var(--tf-mono); font-size: 12px; font-weight: 500; line-height: 1.4; letter-spacing: 0.02em; color: var(--mt-ink-3); }
.tf-stat dt:lang(en) { text-transform: uppercase; letter-spacing: 0.08em; }

@keyframes tf-rise { from { opacity: 0; transform: translateY(12px); } }


/* =====================================================================
 * 01 · Introduction — letters step back, stories step forward
 *
 * The manifesto: two lines in the face, each one line at every width
 * (sized to its box, so a weight change never re-wraps it). At rest the
 * letters stand light and the story heavy; armed by typeface.js, they
 * start the other way round and cross over slowly once, the color
 * crossing with them only during that one passage.
 * ===================================================================== */
.tf-intro { padding-top: clamp(96px, 14vh, 168px); }
.tf-mani {
    container-type: inline-size;
    margin: clamp(28px, 4vw, 48px) 0 clamp(64px, 9vw, 120px);
    line-height: 1.02;
    /* A specimen keeps the spacing the face was drawn with; the size steps
       down a little so the widest line still fits at its heaviest. */
    letter-spacing: 0;
}
.tf-mani-line { display: block; font-size: min(110px, 9.8cqw); white-space: nowrap; }
.tf-mani-line.is-back { font-weight: 200; color: var(--mt-ink-3); }
.tf-mani-line.is-fwd { font-weight: 900; color: var(--mt-ink); }
.tf-mani.is-armed:not(.is-crossed) .is-back { font-weight: 900; color: var(--mt-ink); }
.tf-mani.is-armed:not(.is-crossed) .is-fwd { font-weight: 200; color: var(--mt-ink-3); }
.tf-mani.is-crossing .tf-mani-line { transition: font-weight 2.8s var(--mt-ease) 0.4s, color 2.8s var(--mt-ease) 0.4s; }

.tf-intro-grid {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: clamp(32px, 6vw, 96px);
    align-items: start;
}
.tf-intro-body { display: grid; gap: 1.1em; font-size: clamp(16px, 1.45vw, 19px); line-height: 1.78; color: var(--mt-ink-2); text-wrap: pretty; }
.tf-intro-body strong { font-weight: 600; color: var(--mt-ink); }

/* The one thing the face keeps, as a pull quote on a hairline. */
.tf-quote {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: 16px clamp(32px, 6vw, 96px);
    align-items: start;
    margin-top: clamp(72px, 10vw, 136px);
    padding-top: clamp(28px, 3vw, 40px);
    border-top: 1px solid var(--mt-hair-2);
}
.tf-quote-label { padding-top: 0.9em; font-family: var(--tf-mono); font-size: 12px; font-weight: 500; line-height: 1.4; letter-spacing: 0.02em; color: var(--mt-ink-3); }
.tf-quote-label:lang(en) { text-transform: uppercase; letter-spacing: 0.08em; }
.tf-quote blockquote { margin: 0; font-size: clamp(26px, 3.3vw, 44px); font-weight: 700; line-height: 1.34; letter-spacing: -0.03em; color: var(--mt-ink); text-wrap: balance; }

/* ---------- Marquee: the alphabet passing on the night, light against heavy ---------- */
.tf-marquee { padding: clamp(28px, 4vw, 48px) 0; overflow: clip; background: var(--tf-band); color: var(--tf-band-ink); contain: paint; }
.tf-marquee-row { display: flex; overflow: clip; }
.tf-marquee-row + .tf-marquee-row { margin-top: clamp(6px, 1vw, 14px); }
.tf-marquee-track { display: flex; flex: none; width: max-content; animation: tf-marquee 120s linear infinite; }
.tf-marquee-row.is-reverse .tf-marquee-track { animation-direction: reverse; animation-duration: 140s; opacity: 0.42; }
.tf-marquee-track span { flex: none; padding-right: 0.42em; font-size: clamp(48px, 8vw, 116px); font-weight: var(--w); line-height: 1.06; letter-spacing: 0; white-space: nowrap; }
@keyframes tf-marquee { to { transform: translateX(-50%); } }

/* Whatever moves on its own rests under the pause button and off screen
   (the name is held by typeface.js 2), and until typeface.js is there to
   offer that button: without script the alphabet simply stands. */
html.tf-paused .tf-marquee-track,
.tf-marquee.is-away .tf-marquee-track,
#mt-page.tf-page:not(.is-tf-ready) .tf-marquee-track { animation-play-state: paused; }


/* =====================================================================
 * 02 · Principles — Soft · Even · Open
 *
 * Three cards, the artwork on raised paper (the editor's dotted canvas)
 * and the words beside it, trading sides from card to card; each
 * specimen is labelled in its corners. Each card cuts in as its own
 * scene and lifts a little under a pointer.
 * ===================================================================== */
.tf-pr-list { display: grid; gap: clamp(16px, 2vw, 24px); }
.tf-pr {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    transition: transform 0.6s var(--mt-ease-spring), box-shadow 0.6s var(--mt-ease);
}
.tf-pr-list > :nth-child(even) .tf-pr-art { order: 2; }
.tf-pr-art {
    position: relative;
    display: grid;
    place-items: center;
    min-height: clamp(280px, 32vw, 460px);
    margin: 10px;
    overflow: hidden;
    border-radius: calc(var(--tf-r) - 10px);
    background-color: var(--tf-art);
    color: var(--mt-ink);
}
.tf-pr-art > .tf-svg { width: 78%; }
.tf-pr-num { position: absolute; left: 18px; top: 14px; }
.tf-pr-spec { position: absolute; right: 18px; bottom: 14px; }
.tf-pr-body { display: flex; flex-direction: column; justify-content: center; gap: 12px; padding: clamp(24px, 3.6vw, 52px); }
.tf-pr-word { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; color: var(--mt-ink); }
.tf-pr-word b { font-size: clamp(52px, 6.2vw, 88px); font-weight: 800; line-height: 1; letter-spacing: 0; }
.tf-pr-word span { font-size: 15px; font-weight: 500; color: var(--mt-ink-3); }
.tf-pr-title { margin-top: 10px; font-family: var(--global-font-title); font-size: clamp(21px, 2vw, 28px); font-weight: 700; line-height: 1.3; letter-spacing: 0; text-wrap: balance; }
.tf-pr-text { font-size: 15px; line-height: 1.74; color: var(--mt-ink-2); text-wrap: pretty; }
.tf-pr-facts { margin: 8px 0 0; border-top: 1px solid var(--mt-hair); }
.tf-pr-facts div { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--mt-hair); font-size: 14px; line-height: 1.62; }
.tf-pr-facts dt { padding-top: 2px; font-family: var(--tf-mono); font-size: 12px; font-weight: 500; letter-spacing: 0.02em; color: var(--mt-ink-3); }
.tf-pr-facts dt:lang(en) { text-transform: uppercase; letter-spacing: 0.08em; }
.tf-pr-facts dd { margin: 0; color: var(--mt-ink); }

/* Even: a column of running text, justified, at the size it names. */
.tf-even { display: grid; gap: 14px; width: 82%; max-width: 560px; word-break: normal; overflow-wrap: normal; }
.tf-even-text { font-size: 15px; font-weight: 400; line-height: 1.62; letter-spacing: 0; text-align: justify; hyphens: manual; }
/* Open: wide counters, large, and the same at 13 px. */
.tf-open { display: grid; justify-items: center; gap: clamp(18px, 2.4vw, 28px); width: 100%; }
.tf-open .tf-svg { width: 74%; }
.tf-open-small { display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline; gap: 4px 12px; padding-inline: 16px; font-size: 13px; letter-spacing: 0; text-align: center; }
.tf-open-small .tf-art-label { font-variant-numeric: tabular-nums; }


/* =====================================================================
 * 03 · How it was made — one system, chosen side by side, checked
 *
 * A wide card for the axis (one letter at all nine weights, the three
 * masters ringed on the line), two cards under it, then the tenet:
 * SSHOW's principle, carried into the letters.
 * ===================================================================== */
.tf-mk-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(14px, 1.8vw, 22px); }
.tf-mk { display: flex; flex-direction: column; overflow: clip; }
.tf-mk.is-wide { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); }
.tf-mk-art {
    position: relative;
    display: grid;
    place-items: center;
    min-height: 260px;
    margin: 10px;
    padding: clamp(22px, 3vw, 44px);
    border-radius: calc(var(--tf-r) - 10px);
    background: var(--tf-art);
    color: var(--mt-ink);
}
.tf-mk-art .tf-svg.is-pair { max-width: 420px; }
.tf-mk-spec { position: absolute; right: 16px; bottom: 12px; }
.tf-mk-body { display: grid; align-content: center; gap: 10px; padding: clamp(22px, 2.8vw, 36px); }
.tf-mk-title { font-family: var(--global-font-title); font-size: clamp(21px, 2vw, 28px); font-weight: 700; line-height: 1.3; letter-spacing: 0; }
.tf-mk-text { font-size: 15px; line-height: 1.74; color: var(--mt-ink-2); text-wrap: pretty; }

/* The axis as a row of nine. */
.tf-axis { display: grid; grid-template-columns: repeat(9, minmax(0, 1fr)); justify-items: center; align-items: end; row-gap: 14px; width: 100%; }
.tf-axis-g { font-size: clamp(34px, 6.2vw, 92px); font-weight: var(--w); line-height: 1; letter-spacing: 0; color: var(--mt-ink-3); }
.tf-axis-g.is-master { color: var(--mt-ink); }
.tf-axis-dots { position: relative; grid-column: 1 / -1; display: grid; grid-template-columns: repeat(9, minmax(0, 1fr)); justify-items: center; align-items: center; width: 100%; height: 14px; }
.tf-axis-dots::before { content: ''; position: absolute; left: calc(100% / 18); right: calc(100% / 18); top: 50%; height: 1px; background: var(--mt-hair-2); }
.tf-axis-dots i { position: relative; width: 6px; height: 6px; border-radius: 50%; background: var(--mt-ink-3); }
.tf-axis-dots i.is-master { width: 12px; height: 12px; background: var(--mt-ink); box-shadow: 0 0 0 4px var(--tf-art); }
.tf-axis-val { font-family: var(--tf-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; color: var(--mt-ink-2); }
.tf-axis-m { grid-column: var(--col); display: grid; justify-items: center; gap: 2px; font-family: var(--tf-mono); font-size: 11px; font-weight: 600; letter-spacing: 0.02em; color: var(--mt-ink); white-space: nowrap; }
.tf-axis-m span:lang(en) { text-transform: uppercase; letter-spacing: 0.08em; }
.tf-axis-m small { font-size: 10.5px; font-weight: 500; color: var(--mt-ink-2); }

/* The checks, one line each, with what they check. The label column
   holds the longest label whole (SPACING, 53px). Each line keeps to its
   row at any width: sized from the space beside the label (60px + 12px),
   by the longest line (8.64 em; the face keeps its width at every
   weight). */
.tf-proof { display: grid; gap: 16px; width: 100%; container-type: inline-size; }
.tf-proof div { display: grid; grid-template-columns: 60px minmax(0, 1fr); align-items: baseline; gap: 12px; padding-bottom: 14px; border-bottom: 1px solid var(--mt-hair-2); }
.tf-proof div:last-child { padding-bottom: 0; border-bottom: 0; }
.tf-proof span { font-family: var(--tf-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.02em; color: var(--mt-ink-2); }
.tf-proof span:lang(en) { text-transform: uppercase; letter-spacing: 0.08em; }
.tf-proof p { font-size: min(40px, (100cqi - 72px) / 8.8); font-weight: 500; line-height: 1.1; letter-spacing: 0; white-space: nowrap; }

/* The tenet: a quote on a hairline beside the three lines it holds. */
.tf-tenet {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: 28px clamp(32px, 6vw, 96px);
    align-items: start;
    margin-top: clamp(72px, 10vw, 136px);
    padding-top: clamp(28px, 3vw, 40px);
    border-top: 1px solid var(--mt-hair-2);
}
.tf-tenet-label { margin-bottom: 18px; font-family: var(--tf-mono); font-size: 12px; font-weight: 500; letter-spacing: 0.02em; color: var(--mt-ink-3); }
.tf-tenet-label:lang(en) { text-transform: uppercase; letter-spacing: 0.08em; }
.tf-tenet-quote { font-size: clamp(30px, 3.2vw, 46px); font-weight: 800; line-height: 1.24; letter-spacing: -0.035em; text-wrap: balance; }
.tf-tenet-list { border-top: 1px solid var(--mt-hair); }
.tf-tenet-list li { display: grid; grid-template-columns: 40px minmax(0, 1fr); gap: 4px 14px; padding: 18px 0; border-bottom: 1px solid var(--mt-hair); }
.tf-tenet-list i { padding-top: 5px; font-family: var(--tf-mono); font-size: 12px; font-style: normal; font-weight: 500; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; color: var(--mt-ink-3); }
.tf-tenet-list b { font-family: var(--global-font-title); font-size: 18px; font-weight: 700; letter-spacing: 0; }
.tf-tenet-list p { grid-column: 2; font-size: 15px; line-height: 1.72; color: var(--mt-ink-2); }


/* =====================================================================
 * 04 · Try it — the tester
 *
 * One flat panel: a bar of presets and
 * features, four sliders in a row of cells (values in tabular figures),
 * the line itself on the editor's dotted canvas, and a foot with the CSS
 * for what is set and the panel's tools. The line is a text object: a
 * pointer outlines it in the editor's selection blue; writing in it
 * selects it, with handles and a tag carrying its weight and size.
 * Invert turns the stage over (the night on the lit stage, paper at
 * night). The text's settings travel as custom properties (--t-*) from
 * typeface.js; when the line holds Hangul, a quiet note at the stage's
 * foot says what the face is drawn for.
 * ===================================================================== */
.tf-tool-bar { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 12px 24px; padding: 18px clamp(18px, 2.4vw, 28px); border-bottom: 1px solid var(--mt-hair); }
.tf-tool-controls { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-bottom: 1px solid var(--mt-hair); }
.tf-ctl { padding: 14px clamp(18px, 2.4vw, 28px) 8px; border-right: 1px solid var(--mt-hair); }
.tf-ctl:last-child { border-right: 0; }
/* Label and value share a line; in a narrow cell the value drops under
   its label rather than breaking. */
.tf-ctl-top { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 2px 8px; }
.tf-ctl label { font-size: 12px; font-weight: 500; color: var(--mt-ink-3); }
.tf-ctl output { font-family: var(--tf-mono); font-size: 12px; font-weight: 500; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; color: var(--mt-ink); }
.tf-tool-stage {
    position: relative;
    display: flex;
    align-items: center;
    min-height: clamp(260px, 36vw, 440px);
    /* Room above the line for the selection's tag. */
    padding: clamp(52px, 5.6vw, 80px) clamp(26px, 4vw, 56px) clamp(40px, 5vw, 72px);
    transition: background-color 0.3s var(--mt-ease), color 0.3s var(--mt-ease);
}
.tf-tool-stage.is-inverted {
    --tf-dot: rgba(var(--tf-inverse-ink-rgb), 0.09);
    --mt-sel: var(--tf-inverse-sel);
    background-color: var(--tf-inverse);
    color: var(--tf-inverse-ink);
}
.tf-tool-obj { position: relative; width: 100%; }
.tf-tool-text {
    width: 100%;
    font-size: var(--t-size, clamp(56px, 9vw, 128px));
    font-weight: var(--t-w, 900);
    line-height: var(--t-lead, 1);
    letter-spacing: var(--t-track, 0);
    font-feature-settings: var(--t-feat, normal);
    word-break: normal;
    overflow-wrap: anywhere;
    text-wrap: balance;
    caret-color: currentColor;
}
/* Writing selects the text object, so the selection is the focus ring. */
.tf-tool-text:focus-visible { outline: none; }
.tf-tool-select { inset: -12px -14px; opacity: 0; transition: opacity 0.18s var(--mt-ease); }
.tf-tool-select > i,
.tf-tool-select > .mt-select-tag { opacity: 0; transition: opacity 0.18s var(--mt-ease); }
.tf-tool-select > .mt-select-tag { position: absolute; left: -1px; bottom: calc(100% + 7px); }
.tf-tool-obj:focus-within .tf-tool-select,
.tf-tool-obj:focus-within .tf-tool-select > * { opacity: 1; }
/* The note under the line, in the stage's own ink so it reads turned over
   too; it sits in the stage's bottom padding and never moves the line. */
.tf-tool-note { position: absolute; left: clamp(26px, 4vw, 56px); right: clamp(26px, 4vw, 56px); bottom: clamp(12px, 1.8vw, 24px); font-size: 13px; line-height: 1.5; color: rgba(var(--mt-ink-rgb), 0.72); }
.tf-tool-note[hidden] { display: none; }
.tf-tool-stage.is-inverted .tf-tool-note { color: rgba(var(--tf-inverse-ink-rgb), 0.72); }
.tf-tool-foot { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 12px; padding: 14px clamp(18px, 2.4vw, 28px); border-top: 1px solid var(--mt-hair); }
/* The CSS for what is set: tabular, like every value on the page, so the
   line holds still while a slider moves. */
.tf-css-line { min-width: 0; font-family: var(--tf-mono); font-size: 12px; line-height: 1.5; font-variant-numeric: tabular-nums; color: var(--mt-ink-3); overflow-wrap: anywhere; }
.tf-tool-actions { display: flex; flex-wrap: wrap; gap: 6px; }
/* Invert stays pressed while the stage is inverted. */
.tf-page .tf-tool-actions [aria-pressed="true"] { background: var(--state-selected-bg); }


/* =====================================================================
 * 05 · Weights — nine weights on one axis
 *
 * A big glyph that follows the slider (or a drag across the glyph), the
 * value and its name beside it, then the nine named weights as one radio
 * group: pointing at a row, or reaching it from the keyboard, steps the
 * others back (a click leaves none dimmed); choosing one hands its weight
 * to the glyph above.
 * ===================================================================== */
.tf-scrub { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: clamp(24px, 5vw, 80px); align-items: center; margin-bottom: clamp(40px, 6vw, 72px); }
/* The glyph stands on the hero's hairlines: cap, x-height, baseline. */
.tf-scrub-glyph {
    --lh: 0.82;
    --tf-base: calc((var(--lh) - var(--tf-asc) - var(--tf-dsc)) * 0.5em + var(--tf-asc) * 1em);
    --tf-capl: calc(var(--tf-base) - var(--tf-cap) * 1em);
    --tf-xl: calc(var(--tf-base) - var(--tf-xh) * 1em);
    font-size: clamp(150px, 22vw, 320px);
    font-weight: var(--w, 400);
    line-height: var(--lh);
    letter-spacing: 0;
    white-space: nowrap;
    background-image:
        linear-gradient(to bottom, transparent calc(var(--tf-capl) - 0.5px), var(--mt-hair) calc(var(--tf-capl) - 0.5px), var(--mt-hair) calc(var(--tf-capl) + 0.5px), transparent calc(var(--tf-capl) + 0.5px)),
        linear-gradient(to bottom, transparent calc(var(--tf-xl) - 0.5px), var(--mt-hair) calc(var(--tf-xl) - 0.5px), var(--mt-hair) calc(var(--tf-xl) + 0.5px), transparent calc(var(--tf-xl) + 0.5px)),
        linear-gradient(to bottom, transparent calc(var(--tf-base) - 0.5px), var(--mt-hair-2) calc(var(--tf-base) - 0.5px), var(--mt-hair-2) calc(var(--tf-base) + 0.5px), transparent calc(var(--tf-base) + 0.5px));
    background-repeat: no-repeat;
    cursor: ew-resize;
    touch-action: pan-y;
    user-select: none;
    -webkit-user-select: none;
}
.tf-scrub-glyph.is-easing { transition: font-weight 0.6s var(--mt-ease-spring); }
.tf-scrub-panel { display: grid; gap: 18px; }
.tf-scrub-read { display: flex; flex-wrap: wrap; align-items: baseline; gap: 14px; }
.tf-scrub-num { font-size: clamp(44px, 5vw, 72px); font-weight: 700; line-height: 1; letter-spacing: -0.035em; font-variant-numeric: tabular-nums; }
.tf-scrub-name { font-family: var(--tf-mono); font-size: 13px; font-weight: 500; letter-spacing: 0.08em; text-transform: uppercase; color: var(--mt-ink-2); }
.tf-ticks { display: flex; justify-content: space-between; margin-top: -2px; font-family: var(--tf-mono); font-size: 11px; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; color: var(--mt-ink-3); }

.tf-wrows { border-top: 1px solid var(--mt-hair-2); }
.tf-wrow {
    display: grid;
    grid-template-columns: 56px 120px minmax(0, 1fr);
    align-items: baseline;
    gap: 16px;
    width: 100%;
    padding: clamp(10px, 1.4vw, 16px) 0;
    border-bottom: 1px solid var(--mt-hair);
    text-align: left;
    transition: opacity 0.3s var(--mt-ease), padding-left 0.4s var(--mt-ease-spring);
}
.tf-wrow:focus-visible { outline-offset: -2px; }
.tf-wrow-val { font-family: var(--tf-mono); font-size: 12px; font-weight: 500; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; color: var(--mt-ink-3); }
.tf-wrow-name { font-size: 14px; font-weight: 500; color: var(--mt-ink-2); }
.tf-wrow-sample { overflow: hidden; font-size: clamp(28px, 5.4vw, 78px); font-weight: var(--w); line-height: 1.15; letter-spacing: 0; white-space: nowrap; text-overflow: ellipsis; }
.tf-wrow[aria-checked="true"] .tf-wrow-val { color: var(--mt-ink); }
.tf-wrow[aria-checked="true"] .tf-wrow-val::before { content: ''; display: inline-block; width: 6px; height: 6px; margin-right: 8px; border-radius: 50%; background: currentColor; vertical-align: 2px; }


/* =====================================================================
 * 06 · Glyphs — every character, and the inspector
 *
 * The inspector (sticky beside the grid on a wide screen) and the grid
 * of every character, filtered by kind. On a narrow screen the inspector
 * becomes a sheet rising over a scrim: fixed, so this section drops its
 * scene isolation for the sheet to stand above the page and its header.
 * ===================================================================== */
#mt-page .tf-glyphs.mt-section { isolation: auto; }
.tf-glyphs-layout { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(20px, 3vw, 40px); align-items: start; }
.tf-insp { position: sticky; top: calc(var(--header-height) + 20px); }
.tf-insp-stage { position: relative; margin: 10px 10px 0; overflow: hidden; aspect-ratio: 1400 / 1240; border-radius: calc(var(--tf-r) - 10px); background: var(--tf-art); color: var(--mt-ink); }
.tf-insp-stage .tf-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.tf-insp-stage .tf-guide { opacity: 0.3; }
.tf-insp-stage .tf-guide.is-base { opacity: 0.45; }
.tf-insp-stage .tf-guide.is-side { stroke-dasharray: 3 4; opacity: 0.35; }
.tf-insp-stage text { transition: font-weight 0.3s var(--mt-ease); }
/* The advance between the sidebearings, measured in the editor's blue. */
.tf-measure { stroke: var(--mt-sel); stroke-width: 1; vector-effect: non-scaling-stroke; }
.tf-insp-labels span {
    position: absolute;
    left: 12px;
    top: var(--at);
    font-family: var(--tf-mono);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--mt-ink-2);
    white-space: nowrap;
    transform: translateY(-115%);
}
/* A wide glyph runs under the labels on the left: they sit on a chip of
   the stage's own paper, as an editor's ruler labels do. */
.tf-insp-labels span:not(.tf-insp-measure) { margin-left: -4px; padding: 1px 4px; border-radius: 3px; background: var(--tf-art); }
.tf-insp-labels span.is-right { left: auto; right: 12px; margin: 0 -4px 0 0; }
/* The cap line runs only 40 units under the ascender: its label sits below. */
.tf-insp-labels span.is-below { transform: translateY(25%); }
.tf-insp-labels b { margin-left: 4px; font-weight: 600; color: var(--mt-ink); }
.tf-insp-labels .tf-insp-measure { left: 50%; color: #fff; transform: translate(-50%, -50%); }
.tf-insp-body { display: grid; gap: 14px; padding: 18px clamp(18px, 2vw, 24px) 20px; }
.tf-insp-title { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.tf-insp-name { font-family: var(--global-font-title); font-size: 15px; font-weight: 600; line-height: 1.35; letter-spacing: 0; }
.tf-insp-cp { font-family: var(--tf-mono); font-size: 12px; font-weight: 500; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; color: var(--mt-ink-3); white-space: nowrap; }
.tf-insp-meta { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin: 0; padding: 12px 0; border-block: 1px solid var(--mt-hair); }
.tf-insp-meta dt { font-size: 11px; letter-spacing: 0.02em; color: var(--mt-ink-3); }
.tf-insp-meta dd { margin: 2px 0 0; font-family: var(--tf-mono); font-size: 12.5px; font-weight: 500; letter-spacing: 0.01em; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.tf-insp-ctl { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px; }
.tf-insp-ctl label { font-size: 12px; font-weight: 500; color: var(--mt-ink-3); }
.tf-insp-ctl output { min-width: 3ch; font-family: var(--tf-mono); font-size: 12px; font-weight: 500; font-variant-numeric: tabular-nums; text-align: right; }
.tf-insp-feats[hidden] { display: none; }
.tf-insp-actions { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 8px; }
.tf-insp-nav { display: flex; gap: 6px; }
.tf-insp-close { display: none; position: absolute; top: 18px; right: 18px; z-index: 2; background: var(--tf-card); }

/* The filter by kind, with its counts: one row where the six fit. Where
   they do not (English beside the inspector, at a laptop's width), they
   stand in two rows of three across the column, every kind in view and
   in a mouse's reach (is-rows, measured by typeface.js 6); on a phone
   the row scrolls sideways under a finger instead (below).
   The options that are not chosen and the counts are set in the second
   ink, which holds 4.5:1 on the filter's raised track (the shared
   control's muted ink falls just short there) and on the chosen option. */
.tf-filter-wrap { margin-bottom: 16px; }
.tf-filter { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.tf-filter::-webkit-scrollbar { display: none; }
.tf-filter .di-segmented-option { flex: none; }
.tf-filter.is-rows { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); width: 100%; }
.tf-filter .di-segmented-option:not([aria-checked="true"]) { color: var(--mt-ink-2); }
.tf-count { font-family: var(--tf-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; color: var(--mt-ink-2); }

/* The grid (a listbox): hairlines between every character, the code
   point in the corner on a pointer (in the second ink, which holds 4.5:1
   on the hover's raised fill), the selected one in ink. */
.tf-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(62px, 1fr)); border-top: 1px solid var(--mt-hair); border-left: 1px solid var(--mt-hair); }
.tf-cell {
    position: relative;
    display: grid;
    place-items: center;
    aspect-ratio: 1;
    border-right: 1px solid var(--mt-hair);
    border-bottom: 1px solid var(--mt-hair);
    font-size: clamp(24px, 2.2vw, 30px);
    line-height: 1;
    transition: background-color 0.18s var(--mt-ease), color 0.18s var(--mt-ease), transform 0.3s var(--mt-ease-spring);
}
.tf-cell[hidden] { display: none; }
.tf-cell[aria-selected="true"] { background: var(--mt-ink); color: var(--mt-bg); }
.tf-cell:focus-visible { z-index: 1; outline-offset: -3px; border-radius: 4px; }
/* On the selected (ink) cell the ring is drawn in paper, so it shows. */
.tf-cell[aria-selected="true"]:focus-visible { outline-color: var(--mt-bg); }
.tf-cell small {
    position: absolute;
    left: 6px;
    top: 5px;
    font-family: var(--tf-mono);
    font-size: 9px;
    font-weight: 500;
    letter-spacing: 0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--mt-ink-2);
    opacity: 0;
    transition: opacity 0.18s var(--mt-ease);
}
.tf-cell[aria-selected="true"] small { color: inherit; opacity: 0.6; }
.tf-scrim {
    position: fixed;
    inset: 0;
    z-index: 1090;
    background: rgba(var(--tf-night-rgb), 0.42);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    animation: tf-fade 0.2s var(--mt-ease);
}
.tf-scrim[hidden] { display: none; }
@keyframes tf-fade { from { opacity: 0; } }


/* =====================================================================
 * 07 · Details — a masonry wall of single decisions
 *
 * Columns, not a grid, so each tile keeps its own height. Three tiles
 * are set on the night (paper at night), as the font site set them in
 * ink; a tile that a font feature changes names its tag beside its
 * title.
 * ===================================================================== */
.tf-wall { column-count: 3; column-gap: clamp(14px, 1.8vw, 22px); }
.tf-tile-cut { break-inside: avoid; padding-bottom: clamp(14px, 1.8vw, 22px); }
.tf-tile { transition: transform 0.6s var(--mt-ease-spring), box-shadow 0.6s var(--mt-ease); }
.tf-tile-art { position: relative; display: grid; place-items: center; margin: 8px 8px 0; padding: clamp(24px, 3vw, 40px); border-radius: calc(var(--tf-r-tile) - 8px); background: var(--tf-art); color: var(--mt-ink); }
.tf-tile-art.is-ink { background: var(--tf-inverse); color: var(--tf-inverse-ink); }
.tf-tile-art.is-ink .tf-art-label { color: inherit; opacity: 0.6; }
.tf-tile-art .tf-svg { max-height: 520px; }
.tf-tile-cap { display: grid; gap: 4px; padding: 16px 22px 22px; }
.tf-tile-cap h3 { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; font-family: var(--global-font-title); font-size: clamp(16px, 1.4vw, 18px); font-weight: 600; line-height: 1.35; letter-spacing: 0; }
.tf-tile-cap h3 small { font-family: var(--tf-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.02em; color: var(--mt-ink-3); white-space: nowrap; }
.tf-tile-cap p { font-size: 14px; line-height: 1.6; color: var(--mt-ink-2); }
.tf-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; width: 100%; }
.tf-pair > div,
.tf-rows > div { display: grid; justify-items: center; gap: 10px; }
.tf-rows { display: grid; gap: 18px; width: 100%; }
.tf-nums { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; width: 100%; }
.tf-nums > div { display: grid; gap: 2px; font-size: clamp(22px, 2.4vw, 32px); font-weight: 500; line-height: 1.25; letter-spacing: 0; text-align: right; }
.tf-nums .tf-art-label { margin-bottom: 8px; font-size: 11px; line-height: 1.4; letter-spacing: 0.06em; }


/* =====================================================================
 * 08 · On stage — the hall, then five surfaces
 *
 * The hall: the photo in the hero's rounded frame, its screen covered
 * by the night slide laid on the screen's four corners and cut where
 * the lectern stands in front of it (typeface.js). Projected light
 * has no true black: the slide's ground is lifted to the screen's own
 * grey, its ink dimmed a touch, with a soft hotspot from the projector
 * and a faint glow off the screen's edges. Armed by typeface.js, it
 * switches on once (opacity only, then the slide's own scene cut).
 *
 * The bento: five tiles on twelve columns, the poster and the phone
 * standing tall at the sides. Inside each tile the artwork scales with
 * the tile (container units); a tile lifts a little under a pointer.
 * ===================================================================== */
.tf-hall { margin-bottom: clamp(48px, 7vw, 96px); }
.tf-hall-room {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    aspect-ratio: 16 / 9;
    border-radius: 28px;
    background: var(--tf-hall-ground);
    box-shadow: var(--mt-work-shadow);
    contain: layout paint;
}
.tf-hall-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tf-hall.is-live .tf-hall-photo { inset: auto; left: 0; top: 0; max-width: none; object-fit: fill; transform-origin: 0 0; }
.tf-hall-cast { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.tf-hall-screen {
    position: absolute;
    left: 0;
    top: 0;
    width: 1600px;
    height: 900px;
    overflow: hidden;
    container-type: inline-size;
    transform-origin: 0 0;
    /* Projected light has no razor edge: a soft rim of the slide's own ground. */
    box-shadow: 0 0 10px 2px rgba(var(--tf-projected-rgb), 0.75);
    visibility: hidden;
    pointer-events: none;
}
.tf-hall.is-live .tf-hall-screen { visibility: visible; }
/* Projected night: lifted black, ink a little softer, the projector's
   hotspot and the screen's edges catching less of it. */
.tf-hall-screen .tf-slide {
    --tf-slide-ground: var(--tf-projected);
    --tf-slide-ink: rgba(var(--tf-night-ink-rgb), 0.94);
    --tf-slide-ink-2: rgba(var(--tf-night-ink-rgb), 0.66);
}
/* Seen from the back of the hall, a hairline would break up: the rule
   is drawn a little heavier there. */
.tf-hall-screen .tf-slide-foot { border-top-width: 2px; }
.tf-hall-light {
    position: absolute;
    inset: 0;
    z-index: 2;
    background:
        radial-gradient(60% 70% at 46% 38%, rgba(255, 255, 255, 0.07), transparent 70%),
        radial-gradient(120% 120% at 50% 50%, transparent 60%, rgba(var(--tf-night-rgb), 0.28));
    pointer-events: none;
}
/* The house lights go down a little as the slide comes up: the room
   darkens toward its edges, around the screen (--sx, --sy from
   typeface.js). */
.tf-hall-dim {
    position: absolute;
    inset: 0;
    z-index: 1;
    background: radial-gradient(75% 85% at var(--sx, 45%) var(--sy, 32%), rgba(var(--tf-night-rgb), 0.08), rgba(var(--tf-night-rgb), 0.36) 70%, rgba(var(--tf-night-rgb), 0.5));
    opacity: 0;
    pointer-events: none;
}
.tf-hall.is-live .tf-hall-dim { opacity: 1; }
.tf-hall.is-armed:not(.is-on) .tf-hall-dim { opacity: 0; }
.tf-hall.is-armed.is-on .tf-hall-dim { transition: opacity 2.4s var(--mt-ease) 0.6s; }
.tf-hall.is-armed .tf-hall-screen { opacity: 0; }
.tf-hall.is-armed .tf-hall-screen .tf-slide > :not(.tf-slide-glow) { opacity: 0; transform: scale(1.035); transform-origin: 0 100%; }
.tf-hall.is-armed.is-on .tf-hall-screen { opacity: 1; transition: opacity 1.4s var(--mt-ease); }
.tf-hall.is-armed.is-on .tf-hall-screen .tf-slide > :not(.tf-slide-glow) {
    opacity: 1;
    transform: none;
    transition: opacity 0.9s var(--mt-ease) 0.9s, transform 1.17s var(--mt-ease-spring) 0.9s;
}
.tf-hall-caption { max-width: 46em; margin: 22px auto 0; text-align: center; text-wrap: pretty; }

/* The slide (also the bento's): sized in its own width. */
.tf-slide {
    --tf-slide-ground: var(--tf-night);
    --tf-slide-ink: var(--tf-night-ink);
    --tf-slide-ink-2: var(--tf-night-ink-2);
    position: absolute;
    inset: 0;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    padding: 5.4cqw 6cqw;
    overflow: hidden;
    background: var(--tf-slide-ground);
    color: var(--tf-slide-ink);
}
.tf-slide-glow { position: absolute; right: -12%; top: -34%; z-index: -1; width: 64%; height: 96%; background: radial-gradient(closest-side, rgba(255, 255, 255, 0.1), transparent); }
.tf-slide-top { display: flex; justify-content: space-between; font-size: 1.7cqw; font-weight: 500; letter-spacing: 0; text-transform: uppercase; color: var(--tf-slide-ink-2); }
.tf-slide-title { margin-top: auto; font-size: 8.4cqw; font-weight: 800; line-height: 1; letter-spacing: 0; }
.tf-slide-sub { max-width: 60%; margin-top: 2.4cqw; font-size: 2.1cqw; line-height: 1.5; letter-spacing: 0; color: var(--tf-slide-ink-2); }
.tf-slide-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 4.4cqw; padding-top: 1.8cqw; border-top: 1px solid rgba(var(--tf-night-ink-rgb), 0.12); font-size: 1.6cqw; font-variant-numeric: tabular-nums; color: var(--tf-slide-ink-2); }
/* A slide only a phone wide keeps what still reads: no sub line, the
   small type a little larger. */
@container (max-width: 520px) {
    .tf-slide-sub { display: none; }
    .tf-slide-top,
    .tf-slide-foot { font-size: 2.7cqw; }
    .tf-slide-title { font-size: 9.6cqw; }
}

.tf-bento {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-areas:
        "poster poster poster slide slide slide slide slide slide phone phone phone"
        "poster poster poster app app app figs figs figs phone phone phone";
    gap: clamp(14px, 1.8vw, 22px);
}
.tf-b-cut { display: flex; flex-direction: column; min-width: 0; }
.tf-b-cut.is-poster { grid-area: poster; }
.tf-b-cut.is-slide { grid-area: slide; }
.tf-b-cut.is-phone { grid-area: phone; }
.tf-b-cut.is-app { grid-area: app; }
.tf-b-cut.is-figs { grid-area: figs; }
.tf-b {
    position: relative;
    isolation: isolate;
    display: flex;
    flex: 1;
    flex-direction: column;
    overflow: clip;
    container-type: inline-size;
    border: 1px solid var(--mt-hair);
    border-radius: var(--tf-r-tile);
    background: var(--tf-card);
    color: var(--mt-ink);
    transition: transform 0.6s var(--mt-ease-spring), box-shadow 0.6s var(--mt-ease);
}
.tf-b.is-night { border-color: rgba(var(--tf-night-ink-rgb), 0.06); background: var(--tf-night); color: var(--tf-night-ink); }
.tf-b.is-paper { border-color: rgba(var(--tf-poster-ink-rgb), 0.06); background: var(--tf-poster); color: var(--tf-poster-ink); }
.tf-b-body { position: relative; flex: 1; min-height: 0; }
.tf-b-cap {
    position: relative;
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 11px 16px 12px;
    border-top: 1px solid var(--mt-hair);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.01em;
    color: var(--mt-ink-3);
}
/* The surface keeps its name whole; only the weights wrap, between
   weights (each one a nowrap run, cap.ejs). */
.tf-b-cap > span:first-child { flex: none; white-space: nowrap; }
.tf-b-cap > span:last-child { min-width: 0; font-family: var(--tf-mono); font-size: 11px; letter-spacing: 0.02em; text-align: right; font-variant-numeric: tabular-nums; overflow-wrap: normal; }
.tf-b.is-night .tf-b-cap { border-top-color: rgba(var(--tf-night-ink-rgb), 0.08); color: rgba(var(--tf-night-ink-rgb), 0.62); }
.tf-b.is-paper .tf-b-cap { border-top-color: rgba(var(--tf-poster-ink-rgb), 0.1); color: rgba(var(--tf-poster-ink-rgb), 0.66); }
/* Slide tile: the slide at 16:9. */
.tf-b-cut.is-slide .tf-b-body { flex: none; aspect-ratio: 16 / 9; }

/* Poster tile: ink on warm paper, tall; it grows with its own type
   wherever the grid leaves it shorter than that. */
.tf-b-cut.is-poster .tf-b-body { display: flex; min-height: 140cqw; }
.tf-poster { position: relative; flex: 1; display: flex; flex-direction: column; gap: 4cqw; padding: 7cqw; }
.tf-poster-top { display: flex; justify-content: space-between; font-size: 3.4cqw; font-weight: 600; letter-spacing: 0; font-variant-numeric: tabular-nums; }
.tf-poster-title { margin-top: 4cqw; font-size: 24.5cqw; font-weight: 900; line-height: 0.84; letter-spacing: 0; text-transform: uppercase; }
.tf-poster-num { align-self: flex-end; margin-top: auto; font-size: 44cqw; font-weight: 100; line-height: 0.78; letter-spacing: 0; font-variant-numeric: tabular-nums; }
.tf-poster-rule { height: 1.4cqw; background: currentColor; }
.tf-poster-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 3cqw 4cqw; font-size: 3.6cqw; line-height: 1.3; font-variant-numeric: tabular-nums; }
.tf-poster-grid b { display: block; font-size: 5.4cqw; font-weight: 800; letter-spacing: 0; }

/* Phone tile: a plain, generic handset rising from the tile's floor.
   It is drawn to scale, as the poster is: every size on it is a share of
   the handset's width (--tf-pu, a 300th of it; hairlines stay 1px), so
   its screen keeps the same lines and the same room at any size, and its
   buttons stand clear of the floor. In the wide mosaic's tall tile it
   stands a whole handset high (9:19.5, as /downloads draws one) and a
   little wider, so the tile is not left half empty; out of a wider tile
   (1100px and below) it rises 9:15.5. Should a reader's own text spacing
   still run the screen long, the handset grows taller rather than cut
   it. */
.tf-phone-wrap {
    --tf-pw: min(300px, 86cqw);
    --tf-pu: calc(var(--tf-pw) / 300);
    display: grid;
    justify-items: center;
    align-items: end;
    height: 100%;
    padding-top: 9cqw;
    background: linear-gradient(to bottom, var(--tf-art) 70%, var(--tf-card));
}
.tf-phone {
    width: var(--tf-pw);
    aspect-ratio: 9 / 19.5;
    padding: calc(10 * var(--tf-pu)) calc(10 * var(--tf-pu)) 0;
    border: 1px solid rgba(var(--tf-night-ink-rgb), 0.06);
    border-bottom: 0;
    border-radius: calc(34 * var(--tf-pu)) calc(34 * var(--tf-pu)) 0 0;
    background: var(--tf-night);
    box-shadow: var(--mt-work-shadow);
    color: var(--tf-night-ink);
}
.tf-phone-screen { display: flex; flex-direction: column; gap: calc(12 * var(--tf-pu)); min-height: 100%; padding: calc(14 * var(--tf-pu)) calc(16 * var(--tf-pu)); overflow: hidden; border-radius: calc(26 * var(--tf-pu)) calc(26 * var(--tf-pu)) 0 0; background: var(--tf-night-raise); }
.tf-phone-status { display: flex; justify-content: space-between; align-items: center; font-size: calc(12 * var(--tf-pu)); font-weight: 600; font-variant-numeric: tabular-nums; }
.tf-phone-app { display: flex; justify-content: space-between; align-items: center; margin-top: calc(6 * var(--tf-pu)); }
.tf-phone-app b { font-size: calc(13 * var(--tf-pu)); font-weight: 700; }
.tf-phone-live { padding: calc(3 * var(--tf-pu)) calc(8 * var(--tf-pu)); border-radius: 999px; box-shadow: inset 0 0 0 1px rgba(var(--tf-night-ink-rgb), 0.2); font-size: calc(11 * var(--tf-pu)); font-weight: 600; }
.tf-phone-card { display: grid; gap: calc(4 * var(--tf-pu)); padding: calc(14 * var(--tf-pu)); border-radius: calc(14 * var(--tf-pu)); background: rgba(var(--tf-night-ink-rgb), 0.05); }
.tf-phone-card small { font-size: calc(11 * var(--tf-pu)); letter-spacing: 0; color: var(--tf-night-ink-2); }
.tf-phone-card strong { font-size: calc(20 * var(--tf-pu)); font-weight: 700; line-height: 1.25; letter-spacing: 0; }
.tf-phone-card p { font-size: calc(12.5 * var(--tf-pu)); line-height: 1.5; color: var(--tf-night-ink-2); }
/* The scene count keeps to one line beside the time left. */
.tf-phone-scene { display: flex; justify-content: space-between; align-items: baseline; gap: calc(8 * var(--tf-pu)); font-variant-numeric: tabular-nums; white-space: nowrap; }
.tf-phone-scene b { font-size: calc(40 * var(--tf-pu)); font-weight: 300; line-height: 1; letter-spacing: 0; }
.tf-phone-scene span { font-size: calc(12 * var(--tf-pu)); color: var(--tf-night-ink-2); }
.tf-phone-rail { height: calc(4 * var(--tf-pu)); border-radius: calc(4 * var(--tf-pu)); background: rgba(var(--tf-night-ink-rgb), 0.1); }
.tf-phone-rail i { display: block; width: 25%; height: 100%; border-radius: inherit; background: var(--tf-night-ink); }
.tf-phone-btns { display: grid; grid-template-columns: 1fr 1.6fr; gap: calc(8 * var(--tf-pu)); margin-top: auto; padding-bottom: calc(14 * var(--tf-pu)); }
.tf-phone-btns span { display: grid; place-items: center; height: calc(44 * var(--tf-pu)); border-radius: calc(14 * var(--tf-pu)); background: rgba(var(--tf-night-ink-rgb), 0.07); font-size: calc(14 * var(--tf-pu)); font-weight: 600; }
.tf-phone-btns .is-next { background: var(--tf-night-ink); color: var(--tf-night); }

/* App tile: an export panel, as the editor draws one. */
.tf-app { display: grid; gap: 16px; padding: clamp(18px, 6cqw, 28px); font-size: 14px; }
.tf-app-head { display: flex; justify-content: space-between; align-items: start; gap: 10px; }
.tf-app-title { font-size: 18px; font-weight: 600; line-height: 1.2; letter-spacing: 0; }
.tf-app-meta { margin-top: 4px; font-size: 12.5px; font-variant-numeric: tabular-nums; color: var(--mt-ink-3); }
.tf-app-x { display: grid; flex: none; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--state-hover-bg); color: var(--mt-ink-3); }
.tf-app-x svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.tf-app-seg { display: flex; padding: 3px; border-radius: 10px; background: rgba(var(--mt-ink-rgb), 0.05); }
.tf-app-seg span { flex: 1; padding: 6px 0; border-radius: 7px; font-size: 12.5px; font-weight: 500; text-align: center; color: var(--mt-ink-2); }
.tf-app-seg .is-on { background: var(--tf-card); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08), 0 0 0 1px rgba(var(--mt-ink-rgb), 0.06); font-weight: 600; color: var(--mt-ink); }
.tf-app-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; font-size: 13.5px; }
.tf-app-row small { display: block; font-size: 12px; color: var(--mt-ink-3); }
.tf-app-toggle { position: relative; flex: none; width: 34px; height: 20px; border-radius: 999px; background: var(--mt-ink); }
.tf-app-toggle::after { content: ''; position: absolute; top: 2px; right: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--mt-bg); }
.tf-app-val { font-weight: 600; font-variant-numeric: tabular-nums; }
.tf-app-bar { position: relative; height: 4px; border-radius: 4px; background: var(--mt-hair-2); }
.tf-app-bar i { position: absolute; inset: 0 8% 0 0; border-radius: inherit; background: var(--mt-ink); }
.tf-app-btns { display: flex; justify-content: flex-end; gap: 8px; padding-top: 4px; }
.tf-app-btns span { display: inline-flex; align-items: center; height: 34px; padding: 0 16px; border-radius: 999px; font-size: 13px; font-weight: 600; }
.tf-app-btns .is-ghost { box-shadow: inset 0 0 0 1px var(--mt-hair-2); }
.tf-app-btns .is-solid { background: var(--mt-ink); color: var(--mt-bg); }

/* Figures tile: a clock, a sum and a small table, all tabular. */
.tf-figs { display: grid; gap: 14px; padding: clamp(18px, 6cqw, 28px); }
.tf-figs-top { display: flex; justify-content: space-between; align-items: baseline; font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: uppercase; color: var(--mt-ink-3); }
.tf-figs-clock { font-size: 22cqw; font-weight: 200; line-height: 0.9; letter-spacing: 0; }
.tf-figs-money { font-size: 9.4cqw; font-weight: 700; line-height: 1; letter-spacing: 0; }
.tf-figs-money small { margin-left: 6px; font-size: 0.42em; font-weight: 500; letter-spacing: 0; color: var(--mt-ink-3); }
.tf-figs-table { display: grid; font-size: 13.5px; }
.tf-figs-table div { display: grid; grid-template-columns: 1fr auto auto; gap: 14px; padding: 7px 0; border-top: 1px solid var(--mt-hair); }
.tf-figs-table span:nth-child(2) { font-weight: 600; text-align: right; }
.tf-figs-table span:nth-child(3) { min-width: 6.4ch; text-align: right; white-space: nowrap; color: var(--mt-ink-3); }


/* =====================================================================
 * 09 · Character — four words
 * ===================================================================== */
.tf-persona { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(10px, 1.4vw, 16px); }
.tf-pc-art {
    position: relative;
    display: grid;
    place-items: center;
    height: clamp(150px, 15vw, 200px);
    margin: 8px 8px 0;
    overflow: hidden;
    container-type: inline-size;
    border-radius: calc(var(--tf-r-tile) - 8px);
    background: var(--tf-art);
    color: var(--mt-ink);
}
/* What each word is set in, in the corner. */
.tf-pc-spec { position: absolute; left: 12px; bottom: 10px; }
/* Sized to the card, so the longest word keeps its margins on a phone. */
.tf-pc-art span { position: relative; font-size: min(60px, 23cqw); font-weight: var(--w); line-height: 1; letter-spacing: 0; }
/* Upright stands on a plumb line. */
.tf-pc-art.is-upright::before { content: ''; position: absolute; left: 50%; top: 14%; bottom: 14%; width: 1px; background: var(--mt-hair-2); }
.tf-pc-body { display: grid; gap: 6px; padding: 16px 18px 20px; }
.tf-pc-body h3 { font-family: var(--global-font-title); font-size: clamp(18px, 1.8vw, 22px); font-weight: 600; line-height: 1.3; letter-spacing: 0; }
.tf-pc-body p { font-size: 14px; line-height: 1.62; color: var(--mt-ink-2); text-wrap: pretty; }
.tf-name-rule { margin-top: clamp(28px, 3vw, 40px); padding-top: 18px; border-top: 1px solid var(--mt-hair); font-size: 15px; color: var(--mt-ink-2); }
.tf-name-rule .tf-nb { font-weight: 600; color: var(--mt-ink); }


/* =====================================================================
 * 10 · Now — what this preview is
 *
 * The status in a sentence, and the facts as a sheet of six: the
 * values in the face where they are its own figures and letters.
 * ===================================================================== */
.tf-status-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 32px clamp(32px, 6vw, 96px); align-items: end; }
.tf-status-grid .mt-section-head { margin-bottom: 0; }
.tf-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 0; border-top: 1px solid var(--mt-hair-2); }
/* Value over label, every value standing on the same line whatever its size. */
.tf-facts div { display: grid; grid-template-rows: minmax(calc(clamp(24px, 2.6vw, 36px) * 1.1), auto) auto; align-items: end; row-gap: 10px; padding: 22px 16px 24px 0; border-bottom: 1px solid var(--mt-hair); }
.tf-facts dd { order: -1; margin: 0; font-size: clamp(24px, 2.6vw, 36px); font-weight: 700; line-height: 1.1; letter-spacing: 0; }
.tf-facts dd:not(.tf-face) { font-size: clamp(18px, 1.8vw, 22px); line-height: 1.3; letter-spacing: -0.015em; }
.tf-facts dt { font-family: var(--tf-mono); font-size: 12px; font-weight: 500; letter-spacing: 0.02em; color: var(--mt-ink-3); }
.tf-facts dt:lang(en) { text-transform: uppercase; letter-spacing: 0.08em; }


/* =====================================================================
 * Close — the last line, standing up
 *
 * The closing line in the face on the hero's hairlines, centered. Armed
 * by typeface.js, it starts in Thin and rises into its weight once, as
 * if standing up; then the way in and the way back.
 * ===================================================================== */
.tf-close { padding-block: clamp(104px, 15vh, 180px) clamp(72px, 10vh, 120px); }
.tf-close-inner { text-align: center; }
.tf-close-title {
    --lh: 0.98;
    --tf-base: calc((var(--lh) - var(--tf-asc) - var(--tf-dsc)) * 0.5em + var(--tf-asc) * 1em);
    --tf-capl: calc(var(--tf-base) - var(--tf-cap) * 1em);
    --tf-xl: calc(var(--tf-base) - var(--tf-xh) * 1em);
    font-size: clamp(44px, 8.6vw, 132px);
    font-weight: 800;
    line-height: var(--lh);
    letter-spacing: 0;
    background-image:
        linear-gradient(to bottom, transparent calc(var(--tf-capl) - 0.5px), var(--mt-hair) calc(var(--tf-capl) - 0.5px), var(--mt-hair) calc(var(--tf-capl) + 0.5px), transparent calc(var(--tf-capl) + 0.5px)),
        linear-gradient(to bottom, transparent calc(var(--tf-base) - 0.5px), var(--mt-hair-2) calc(var(--tf-base) - 0.5px), var(--mt-hair-2) calc(var(--tf-base) + 0.5px), transparent calc(var(--tf-base) + 0.5px));
    background-size: 100% calc(var(--lh) * 1em);
    background-repeat: repeat-y;
}
.tf-close-line { display: block; white-space: nowrap; }
.tf-close-title.is-armed:not(.is-up) .tf-close-line { font-weight: 100; }
.tf-close-title.is-up .tf-close-line { transition: font-weight 2.4s var(--mt-ease-spring) 0.2s; }
.tf-close-title.is-up .tf-close-line + .tf-close-line { transition-delay: 0.45s; }
.tf-close-sub { max-width: 28em; margin: clamp(24px, 3vw, 36px) auto 0; font-size: clamp(18px, 2vw, 24px); line-height: 1.5; letter-spacing: -0.02em; color: var(--mt-ink-2); text-wrap: balance; }
.tf-close-actions { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 12px; margin-top: 36px; }


/* ---------- Pointer devices: hover answers only where there is a hover ---------- */
@media (hover: hover) {
    .tf-back:hover .mt-link-arrow { transform: translateX(-4px); }
    /* A way down the page leans down. */
    .tf-actions .di-btn:hover .mt-link-arrow { transform: translateY(3px); }
    .tf-motion:hover { box-shadow: inset 0 0 0 1px rgba(var(--mt-ink-rgb), 0.4); color: var(--mt-ink); }
    .tf-chip:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px rgba(var(--mt-ink-rgb), 0.4); color: var(--mt-ink); }
    .tf-chip:is([aria-pressed="true"], [aria-checked="true"]):hover { box-shadow: none; color: var(--mt-bg); }
    .tf-icon-btn:hover { background: var(--state-hover-bg); box-shadow: inset 0 0 0 1px rgba(var(--mt-ink-rgb), 0.36); }
    /* A card lifts a little: a soft shadow, no light. */
    .tf-pr:hover,
    .tf-tile:hover { transform: translateY(-3px); box-shadow: inset 0 0 0 1px var(--mt-hair), var(--tf-lift); }
    .tf-b:hover { transform: translateY(-3px); box-shadow: var(--tf-lift); }
    /* A pointer over the tester's line outlines the text object, as the
       editor does before a press. */
    .tf-tool-obj:hover .tf-tool-select { opacity: 1; }
    /* The rows step back for a pointer or keyboard focus only, once they
       work: a click focuses a row without :focus-visible, so nothing
       stays dimmed. The row being read stands out; its rule is more
       specific than both above it, so it wins. */
    .tf-wrows:hover .tf-wrow:not(:disabled),
    .tf-wrows:has(.tf-wrow:focus-visible) .tf-wrow { opacity: 0.32; }
    .tf-page .tf-wrows .tf-wrow:not(:disabled):is(:hover, :focus-visible) { opacity: 1; padding-left: 8px; }
    .tf-filter .di-segmented-option:not([aria-checked="true"]):hover { color: var(--mt-ink); }
    .tf-cell:not(:disabled):hover { z-index: 1; background: var(--state-hover-bg); transform: scale(1.04); box-shadow: 0 0 0 1px var(--mt-hair-2); }
    .tf-cell[aria-selected="true"]:not(:disabled):hover { background: var(--mt-ink); }
    .tf-cell:not(:disabled):hover small { opacity: 1; }
}
/* ---------- Touch: 44px targets ---------- */
@media (hover: none) {
    .tf-chip::after,
    .tf-page .di-btn-sm::after { content: ''; position: absolute; inset: -6px 0; }
    .tf-page .di-btn-sm { position: relative; }
    .tf-motion { position: relative; }
    .tf-motion::after { content: ''; position: absolute; inset: -6px; }
    .tf-icon-btn { width: 44px; height: 44px; }
    .tf-range { height: 44px; }
    .tf-filter .di-segmented-option { height: 44px; }
    .tf-scrub-glyph { cursor: default; }
}

/* ---------- Wide screens: the ruler fits in the margin ---------- */
@media (min-width: 1100px) {
    .tf-ruler { display: block; }
}

/* ---------- Wide tablets (1100px) ---------- */
@media (max-width: 1100px) {
    .tf-wrow-sample { font-size: clamp(26px, 4.6vw, 60px); }
    .tf-wall { column-count: 2; }
    .tf-bento {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-template-areas: "slide slide" "poster phone" "app figs";
    }
    /* The handset rises out of a wider tile, no longer a whole one. */
    .tf-phone-wrap { --tf-pw: min(300px, 80cqw); }
    .tf-phone { aspect-ratio: 9 / 15.5; }
    .tf-persona { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .tf-status-grid { grid-template-columns: minmax(0, 1fr); align-items: start; }
}

/* ---------- Content fold (880px) ----------
   The two-column layouts stack; the name breaks after SEO (never
   leaving it alone); the inspector becomes a sheet over a scrim. */
@media (max-width: 880px) {
    #mt-page.tf-page { --tf-r: 24px; }
    .tf-name { --tf-lines: 2; font-size: calc(100cqw / 6.15); }
    .tf-w:last-child { display: block; }
    .tf-hero-sub { grid-template-columns: minmax(0, 1fr); }
    .tf-hero-copy { justify-self: start; }
    .tf-stats { grid-template-columns: repeat(3, auto); justify-content: start; gap: 20px 40px; }
    .tf-intro-grid,
    .tf-quote,
    .tf-tenet { grid-template-columns: minmax(0, 1fr); }
    .tf-pr { grid-template-columns: minmax(0, 1fr); }
    .tf-pr-list > :nth-child(even) .tf-pr-art { order: 0; }
    .tf-pr-art { min-height: 0; aspect-ratio: 4 / 3; }
    .tf-pr-art:has(.tf-even),
    .tf-pr-art:has(.tf-open) { aspect-ratio: auto; padding: 48px 0 32px; }
    .tf-pr-art .tf-even { width: calc(100% - 48px); }
    .tf-pr-body { padding-top: 12px; }
    .tf-mk-grid { grid-template-columns: minmax(0, 1fr); }
    .tf-mk.is-wide { grid-template-columns: minmax(0, 1fr); }
    .tf-mk.is-wide .tf-mk-art { order: -1; }
    .tf-tool-controls { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .tf-ctl:nth-child(2) { border-right: 0; }
    .tf-ctl:nth-child(-n + 2) { border-bottom: 1px solid var(--mt-hair); }
    .tf-scrub { grid-template-columns: minmax(0, 1fr); }
    .tf-wrow { grid-template-columns: 56px minmax(0, 1fr); row-gap: 2px; }
    .tf-wrow-sample { grid-column: 1 / -1; font-size: clamp(26px, 6vw, 52px); }
    .tf-glyphs-layout { grid-template-columns: minmax(0, 1fr); }
    .tf-insp {
        position: fixed;
        left: 0;
        right: 0;
        top: auto;
        bottom: 0;
        z-index: 1100;
        max-height: 88svh;
        padding-top: 48px;
        overflow-y: auto;
        border-radius: 18px 18px 0 0;
        visibility: hidden;
        transform: translateY(105%);
        transition: transform 0.36s var(--mt-ease-spring), visibility 0s linear 0.36s;
    }
    .tf-insp.is-open { visibility: visible; transform: none; transition: transform 0.36s var(--mt-ease-spring), visibility 0s; }
    .tf-insp::before { content: ''; position: absolute; left: 50%; top: 10px; width: 36px; height: 4px; margin-left: -18px; border-radius: 4px; background: var(--mt-hair-2); }
    .tf-insp-close { display: inline-grid; top: 8px; right: 12px; }
    .tf-insp-stage { width: calc(100% - 20px); max-height: 44svh; margin-inline: auto; }
    .tf-hall-room { aspect-ratio: 4 / 3; border-radius: 24px; }
}

/* ---------- Phones (640px) ---------- */
@media (max-width: 640px) {
    #mt-page.tf-page { --tf-r: 20px; --tf-r-tile: 20px; }
    .tf-meta { margin-bottom: 32px; }
    .tf-hero { min-height: 0; }
    .tf-hero-eyebrow { margin-top: 32px; }
    .tf-hero-sub { margin-bottom: 48px; }
    .tf-stats { grid-template-columns: repeat(3, auto); justify-content: space-between; gap: 22px 16px; }
    .tf-stat.is-wide { grid-column: 1 / -1; }
    .tf-even-text { text-align: left; }
    .tf-wall { column-count: 1; }
    .tf-bento { grid-template-columns: minmax(0, 1fr); grid-template-areas: "slide" "poster" "phone" "app" "figs"; }
    .tf-b-cut.is-phone .tf-b-body { min-height: 112cqw; }
    .tf-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .tf-hall-room { border-radius: 20px; }
}

/* ---------- Small phones (560px) ---------- */
@media (max-width: 560px) {
    /* The pause control keeps only its icon, so the back link keeps its row. */
    .tf-motion { justify-content: center; width: 32px; padding: 0; gap: 0; font-size: 0; }
    .tf-wrow { grid-template-columns: 44px minmax(0, 1fr); }
    .tf-axis-m { font-size: 10px; }
    .tf-axis-m small { display: none; }
    .tf-mk-art { min-height: 0; }
    .tf-grid { grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); }
    .tf-cell { font-size: 22px; }
    .tf-cell small { display: none; }
    /* The filter scrolls sideways; the fade at its edge says there is more. */
    .tf-filter { -webkit-mask-image: linear-gradient(to right, #000 85%, transparent); mask-image: linear-gradient(to right, #000 85%, transparent); }
    .tf-filter.is-end { -webkit-mask-image: none; mask-image: none; }
    .tf-persona { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    .tf-pc-body { padding: 14px 14px 18px; }
}

/* ---------- Low landscape ----------
   The name goes back to one line (two would fill the screen), and a
   wide-but-low window keeps the inspector in the flow: a sticky panel
   taller than the screen would hide its own controls. */
@media (max-height: 540px) and (orientation: landscape) {
    .tf-hero { min-height: 0; }
    .tf-name { --tf-lines: 1; font-size: calc(100cqw / 8.6); }
    .tf-w:last-child { display: inline; }
}
@media (min-width: 881px) and (max-height: 540px) and (orientation: landscape) {
    .tf-insp { position: relative; top: auto; }
}

/* ---------- Dark: the night stage ---------- */
@media (prefers-color-scheme: dark) {
    #mt-page.tf-page {
        --tf-band: var(--mt-bg-raise);
        --tf-band-ink: var(--mt-ink);
        --tf-dot: rgba(var(--mt-ink-rgb), 0.06);
        --tf-lift: 0 24px 48px -28px rgba(0, 0, 0, 0.75), inset 0 0 0 1px rgba(var(--mt-ink-rgb), 0.04);
        /* Turned over at night: paper under ink. */
        --tf-inverse: var(--tf-night-ink);
        --tf-inverse-ink: var(--tf-night);
        --tf-inverse-ink-rgb: var(--tf-night-rgb);
        --tf-inverse-sel: #185CC2;
    }
    .tf-scrim { background: rgba(var(--tf-night-rgb), 0.62); }
    /* The night's own pictures rise off the night page, as /design's
       night panel does: the slide tile and the handset on the night's
       raise with a firmer edge, the handset's screen sinking back to the
       night inside it. */
    .tf-b.is-night { border-color: var(--mt-hair-2); background: var(--mt-bg-raise); }
    .tf-b.is-night .tf-slide { --tf-slide-ground: var(--mt-bg-raise); }
    .tf-phone { border-color: var(--mt-hair-2); background: var(--mt-bg-raise); }
    .tf-phone-screen { background: var(--tf-night); }
}

/* ---------- Reduced motion ----------
   marketing.css stops every animation and transition under #mt-page and
   typeface.js leaves the name alone: it stands at Regular, the lights
   and the marquee hold still, the manifesto and the close stand at their
   final weights. Nothing moves on its own, so the pause button has
   nothing to pause. */
@media (prefers-reduced-motion: reduce) {
    .tf-motion { display: none; }
}

/* ---------- Forced colors: Windows contrast themes ----------
   The system paints the page in its own few colors and drops shadows,
   tints and gradients, so every state drawn with them is redrawn here in
   system colors, as on /design: borders mark the controls and the tools'
   panels, Highlight marks what is chosen, pressed or selected (where the
   editor's blue stands elsewhere), and the diagrams keep their ink. The
   hall is a photo with the slide laid on its screen, so it keeps its own
   colors, as a picture does. */
@media (forced-colors: active) {
    /* Surfaces keep an edge where their hairline was a shadow. */
    #mt-page.tf-page :is(.tf-card, .tf-panel) { outline: 1px solid CanvasText; outline-offset: -1px; }

    /* Controls that draw no border of their own get one. */
    #mt-page.tf-page :is(.tf-chip, .tf-icon-btn, .tf-motion) { border: 1px solid ButtonText; }

    /* Sliders: the system's own, ringed when reached by the keyboard (the
       thumb's ring was a shadow). */
    .tf-range,
    .tf-range::-webkit-slider-thumb { -webkit-appearance: auto; appearance: auto; }
    .tf-range:focus-visible { outline: 2px solid Highlight; outline-offset: 2px; }

    /* Chosen, pressed and selected: Highlight, with its own text. */
    #mt-page.tf-page :is([aria-pressed="true"], [aria-checked="true"]:is(.tf-chip, .di-segmented-option), .tf-cell[aria-selected="true"]) {
        forced-color-adjust: none;
        border-color: Highlight;
        background: Highlight;
        box-shadow: none;
        color: HighlightText;
    }
    #mt-page.tf-page :is([aria-pressed="true"], [aria-checked="true"]:is(.tf-chip, .di-segmented-option)):focus-visible { outline-color: CanvasText; }
    /* The chosen kind's count reads in the option's own text. */
    #mt-page.tf-page .di-segmented-option[aria-checked="true"] .tf-count { color: inherit; }
    /* A cell's ring is drawn inside it, on the Highlight. */
    #mt-page.tf-page .tf-cell[aria-selected="true"]:focus-visible { outline-color: HighlightText; }
    /* The weight in use keeps its dot. */
    .tf-wrow[aria-checked="true"] .tf-wrow-val::before { forced-color-adjust: none; background: Highlight; }

    /* The tester's line: its selection, handles and tag in Highlight;
       turned over, the stage takes the system's ink for its ground, and
       the selection the ground's own ink (Highlight need not show on it).
       The inspector measures in Highlight too. */
    .tf-tool-select { outline-color: Highlight; }
    .tf-tool-select > i { border-color: Highlight; }
    #mt-page.tf-page .tf-tag { forced-color-adjust: none; background: Highlight; color: HighlightText; }
    .tf-tool-stage.is-inverted { forced-color-adjust: none; background: CanvasText; color: Canvas; }
    .tf-tool-stage.is-inverted .tf-tool-note { color: Canvas; }
    .tf-tool-stage.is-inverted .tf-tool-select { outline-color: Canvas; }
    .tf-tool-stage.is-inverted .tf-tool-select > i { border-color: Canvas; background: CanvasText; }
    .tf-measure { stroke: Highlight; }

    /* The axis (03): its line and its nine weights. */
    .tf-axis-dots::before,
    .tf-axis-dots i { forced-color-adjust: none; background: CanvasText; box-shadow: none; }

    /* The pictures of the face at work (08) keep their working parts: the
       buttons and bars drawn in them get an edge, the poster its rule, and
       the export panel's choice and switch stand in Highlight. */
    :is(.tf-app-seg, .tf-app-x, .tf-app-btns span, .tf-app-bar, .tf-phone-live, .tf-phone-btns span, .tf-phone-rail) { border: 1px solid CanvasText; }
    :is(.tf-app-bar i, .tf-phone-rail i, .tf-poster-rule) { forced-color-adjust: none; background: CanvasText; }
    :is(.tf-app-seg .is-on, .tf-app-toggle) { forced-color-adjust: none; background: Highlight; box-shadow: none; color: HighlightText; }
    .tf-app-toggle::after { forced-color-adjust: none; background: HighlightText; }
    .tf-hall-room { forced-color-adjust: none; }
}
