/* ============================================================================
   type.css: the type system for the inner pages (owner: type package,
   CINEMATIC-PLAN item 4). Loaded after every page stylesheet.

   The set is A, Brand editorial (Amir, 2026-09-25): Orbitron display, Geist
   body, Share Tech Mono labels. Its values are tokens (tokens.css); these
   rules read them.

   Scope: the service pages (body.tsv-page) and the rooms (body.room-page:
   /projects, /project/*, /welcome, /404, /robot). Nothing here matches the
   homepage (home-page) or the business card (card-page), and the faces
   declared below are only fetched when something on the page is set in them,
   so a page downloads the active set's files and nothing else.

   Specificity, on purpose:
     1. Base elements (section 2): at most one type selector, (0,0,1), with the
        page scope inside :where(). They beat site.css's own h1..h6, body and
        strong rules (same weight, later file) and lose to any class rule, so
        a component from any package wins.
     2. Bridges (section 3): existing site.css / pages.css components whose type
        is hard coded or sits on the wrong token. Each one has exactly the
        specificity of the rule it corrects, (0,1,0) for a class and (0,1,1)
        for the three class + element rules (.cform-head h2, .cform-head p,
        .cform-field fields), and sets only type properties, every value a
        token. A component that wants other type sets the token on itself
        (custom properties inherit, no specificity fight), or styles its own
        class with one more class.
   ========================================================================== */

/* ------------------------------------------------------------- 1. faces */

/*
 * Self hosted latin subsets, the files fonts.gstatic.com serves Chrome, each
 * with its OFL licence in /assets/fonts/licenses/. Orbitron and Share Tech
 * Mono are declared in the head partial (the homepage uses them too).
 * Variable faces: one file covers every weight.
 */
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/assets/fonts/geist-100-900-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;
}

/*
 * Metric matched fallbacks: what paints before the web font arrives, sized so
 * the swap moves nothing. A local face (Arial, Times New Roman, Courier New;
 * Liberation, Roboto and Noto where those are missing) scaled to the web
 * font's width and given its ascent and descent. size-adjust is measured on
 * this site's own text, per weight in use (the display faces are set heavy,
 * so their bold fallback is matched on bold): every lede, prose, FAQ and case
 * study paragraph of the built pages for the copy faces, every h1 and h2 for
 * the display faces (in capitals, as they are set), measured in Chrome against
 * Arial, Arial Bold, Times New Roman and Courier New. The overrides are the
 * web font's own hhea/typo metrics divided by size-adjust.
 */
@font-face {
  font-family: 'Orbitron Fallback';
  font-weight: 100 549;
  src: local('Arial'), local('ArialMT'), local('Liberation Sans'), local('Roboto'), local('Roboto-Regular');
  size-adjust: 115.45%;
  ascent-override: 87.57%;
  descent-override: 21.05%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Orbitron Fallback';
  font-weight: 550 900;
  src: local('Arial Bold'), local('Arial-BoldMT'), local('Liberation Sans Bold'), local('Roboto Bold'), local('Roboto-Bold');
  size-adjust: 114.96%;
  ascent-override: 87.95%;
  descent-override: 21.14%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Geist Fallback';
  font-weight: 100 549;
  src: local('Arial'), local('ArialMT'), local('Liberation Sans'), local('Roboto'), local('Roboto-Regular');
  size-adjust: 102.56%;
  ascent-override: 97.99%;
  descent-override: 28.76%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Geist Fallback';
  font-weight: 550 900;
  src: local('Arial Bold'), local('Arial-BoldMT'), local('Liberation Sans Bold'), local('Roboto Bold'), local('Roboto-Bold');
  size-adjust: 99.11%;
  ascent-override: 101.4%;
  descent-override: 29.76%;
  line-gap-override: 0%;
}

@font-face {
  font-family: 'Share Tech Mono Fallback';
  font-weight: 100 900;
  src: local('Courier New'), local('CourierNewPSMT'), local('Liberation Mono'), local('Noto Sans Mono'), local('Roboto Mono');
  size-adjust: 91%;
  ascent-override: 97.26%;
  descent-override: 26.59%;
  line-gap-override: 0%;
}

/* ------------------------------------------------------ 2. base elements */

body:where(.tsv-page, .room-page) {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: var(--weight-body);
  line-height: var(--lh-body);
  /* The label and serif faces have one weight each: a bold request renders
     the real weight rather than a smeared synthetic one. */
  font-synthesis: style;
  font-kerning: normal;
  font-optical-sizing: auto;
  -moz-osx-font-smoothing: grayscale;
}

:where(.tsv-page, .room-page) :is(h1, h2, h3, h4) {
  text-wrap: balance;
}

:where(.tsv-page, .room-page) h1 {
  font-family: var(--font-display);
  font-size: var(--fs-h1);
  font-weight: var(--weight-display);
  line-height: var(--lh-display);
  letter-spacing: var(--tracking-display);
  text-transform: var(--case-display);
}

:where(.tsv-page, .room-page) h2 {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: var(--weight-heading);
  line-height: var(--lh-heading);
  letter-spacing: var(--tracking-heading);
  text-transform: var(--case-heading);
}

:where(.tsv-page, .room-page) h3 {
  font-family: var(--font-h3);
  font-size: var(--fs-h3);
  font-weight: var(--weight-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--tracking-h3);
  text-transform: var(--case-heading);
}

:where(.tsv-page, .room-page) h4 {
  font-family: var(--font-body);
  font-size: var(--fs-h4);
  font-weight: var(--weight-strong);
  line-height: var(--lh-h4);
  letter-spacing: 0;
}

:where(.tsv-page, .room-page) :where(p, li, dd, figcaption, blockquote) {
  text-wrap: pretty;
}

:where(.tsv-page, .room-page) :is(strong, b) {
  font-weight: var(--weight-strong);
}

:where(.tsv-page, .room-page) small {
  font-size: var(--fs-small);
}

:where(.tsv-page, .room-page) blockquote {
  font-family: var(--font-quote);
  font-size: var(--fs-quote);
  line-height: var(--lh-quote);
  hanging-punctuation: first;
}

:where(.tsv-page, .room-page) figcaption {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}

:where(.tsv-page, .room-page) :is(label, code, kbd, samp) {
  font-family: var(--font-label);
}

:where(.tsv-page, .room-page) :is(input, select, textarea) {
  font-family: var(--font-body);
  /* 16px or more, or iOS zooms the page when a field takes focus */
  font-size: max(1rem, 1em);
}

:where(.tsv-page, .room-page) button {
  font-family: var(--font-button);
  font-weight: var(--weight-button);
  letter-spacing: var(--tracking-button);
}

:where(.tsv-page, .room-page) th {
  font-family: var(--font-label);
  font-size: var(--fs-label);
  font-weight: 400;
  letter-spacing: var(--tracking-label);
  text-align: left;
  text-transform: uppercase;
}

:where(.tsv-page, .room-page) td {
  font-size: var(--fs-small);
  line-height: var(--lh-small);
}

/* ----------------------------------------------------------- 3. bridges */

/* ---- titles and headings on the display face -------------------------- */

/* The service page's title opens the page: it is set at hero scale. The
   heroes package can re-point --fs-h1 on its own hero if it wants another. */
:where(.tsv-page) :where(.svc-hero) {
  --fs-h1: var(--fs-hero);
}

:where(.tsv-page, .room-page) :is(.svc-h1, .case-h1, .nf-h1) {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  letter-spacing: var(--tracking-display);
  text-transform: var(--case-display);
}

:where(.tsv-page, .room-page) :is(.case-h1, .nf-h1) {
  font-size: var(--fs-h1);
  line-height: var(--lh-display);
}

/* written in capitals: tracked open, whatever the set does with case */
:where(.tsv-page, .room-page) .nf-h1 {
  letter-spacing: var(--tracking-caps);
}

:where(.tsv-page, .room-page) :is(.svc-h2, .aeo-h, .faq-h, .results-h) {
  font-family: var(--font-display);
  font-weight: var(--weight-heading);
  letter-spacing: var(--tracking-heading);
  text-transform: var(--case-heading);
}

:where(.tsv-page, .room-page) .results-h {
  font-size: var(--fs-h2);
  line-height: var(--lh-heading);
}

:where(.tsv-page, .room-page) .cform-head h2 {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: var(--weight-heading);
  line-height: var(--lh-heading);
  letter-spacing: var(--tracking-heading);
  text-transform: var(--case-heading);
}

:where(.tsv-page, .room-page) .svc-h3 {
  font-family: var(--font-h3);
  font-weight: var(--weight-h3);
  letter-spacing: var(--tracking-h3);
}

/* titles written or set in capitals */
:where(.tsv-page, .room-page) :is(.tier-price, .case-part-label, .mission-name, .ms-panel-t) {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  letter-spacing: var(--tracking-caps);
}

:where(.tsv-page, .room-page) :is(.case-part-label, .mission-name) {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
}

:where(.tsv-page, .room-page) .ms-panel-t {
  font-size: calc(var(--fs-h3) * 1.1);
}

:where(.tsv-page, .room-page) .ms-h {
  font-family: var(--font-hud);
  font-weight: var(--weight-hud);
}

/* ---- numbers ------------------------------------------------------------ */

:where(.tsv-page, .room-page) :is(.score-num, .results-num, .tsv-proof-num, .toai-w-stat) {
  font-family: var(--font-display);
  font-weight: var(--weight-stat);
  letter-spacing: var(--tracking-display);
  font-variant-numeric: lining-nums;
}

:where(.tsv-page, .room-page) .score-num {
  font-size: var(--fs-stat);
  line-height: 1;
}

/* four to a row on /welcome: a card is 190px wide at its narrowest */
:where(.tsv-page, .room-page) .results-num {
  font-size: var(--fs-stat-card);
  line-height: 1;
}

/* proof figures inside a hero or a caption: a step above the h3, not a
   scoreboard, so they never outshout the title */
:where(.tsv-page, .room-page) :is(.tsv-proof-num, .toai-w-stat) {
  font-size: calc(var(--fs-h3) * 1.2);
  line-height: 1.1;
}

/* ---- the wordmark --------------------------------------------------------- */

:where(.tsv-page, .room-page) :is(.topbar-brand, .frame-tab) {
  font-family: var(--font-wordmark);
  font-weight: var(--weight-wordmark);
  letter-spacing: var(--tracking-wordmark);
}

:where(.tsv-page, .room-page) .topbar-brand {
  font-size: var(--fs-wordmark);
}

:where(.tsv-page, .room-page) .frame-tab {
  font-size: var(--fs-plate);
}

/* ---- labels: the mono readout face ---------------------------------------- */

:where(.tsv-page, .room-page) :is(.frame-tab--quiet, .case-kicker, .mission-kicker, .mission-title, .mission-hint) {
  font-family: var(--font-label);
  font-size: var(--fs-label);
  font-weight: 400;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

:where(.tsv-page, .room-page) :is(.work-name, .score-label, .block-tag, .results-win) {
  font-family: var(--font-label);
  letter-spacing: var(--tracking-label);
}

/* the guide's furniture, which names its face outright in site.css */
:where(.tsv-page, .room-page) :is(.toai-tip, .toai-help-btn, .toai-help-panel) {
  font-family: var(--font-label);
  font-weight: 400;
}

/* its h4 would otherwise take the base h4's copy face */
:where(.tsv-page, .room-page) .toai-help-panel h4 {
  font-family: var(--font-label);
}

/* ---- buttons -------------------------------------------------------------- */

:where(.tsv-page, .room-page) :is(.btn, .nf-btn, .ms-deploy, .toai-submit-btn) {
  font-family: var(--font-button);
  font-size: var(--fs-button);
  font-weight: var(--weight-button);
  letter-spacing: var(--tracking-button);
  text-transform: uppercase;
}

/* ---- running copy --------------------------------------------------------- */

:where(.tsv-page, .room-page) :is(.aeo-inner, .faq-inner, .results) {
  font-family: var(--font-body);
}

:where(.tsv-page, .room-page) .lede {
  max-width: var(--measure-lead);
}

:where(.tsv-page, .room-page) .prose {
  margin-bottom: 0.9em;
}

:where(.tsv-page, .room-page) :is(.bullets, .steps) {
  max-width: var(--measure);
}

:where(.tsv-page, .room-page) :where(.bullets, .steps) > li + li {
  margin-top: 0.45em;
}

:where(.tsv-page, .room-page) :is(.faq-a, .case-prose, .nf-text) {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}

:where(.tsv-page, .room-page) .pullquote {
  font-family: var(--font-quote);
  font-size: var(--fs-quote);
  line-height: var(--lh-quote);
}

:where(.tsv-page, .room-page) :is(.faq-q, .aeo-sub) {
  font-size: var(--fs-h4);
  letter-spacing: 0;
}

/* an h3 by markup, a table caption by role: the copy face, not the display */
:where(.tsv-page, .room-page) .aeo-sub {
  font-family: var(--font-body);
  font-weight: var(--weight-strong);
  line-height: var(--lh-h4);
}

/* the webflow figcaption default centred these under left set names */
:where(.tsv-page, .room-page) .work-cap {
  text-align: left;
}

/* small print */
:where(.tsv-page, .room-page) :is(.microline, .fineprint, .work-meta, .work-note, .footer-area, .footer-meta, .cmp-table, .results-lede, .results-label, .mission-note, .cform-call) {
  font-family: var(--font-body);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  letter-spacing: 0;
}

:where(.tsv-page, .room-page) .cform-head p {
  font-family: var(--font-body);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  letter-spacing: 0;
}

/* the comparison table: cells need air once the copy is proportional */
:where(.tsv-page, .room-page) :where(.cmp-table) :is(th, td) {
  padding: 0.7em 1.2em 0.7em 0;
  vertical-align: top;
  border-bottom: 1px solid var(--rule);
}

/* ---- the contact form ----------------------------------------------------- */

:where(.tsv-page, .room-page) .cform-field :is(input, select, textarea) {
  font-family: var(--font-body);
  font-size: max(1rem, var(--fs-small));
}

:where(.tsv-page, .room-page) .cform-field :is(input, textarea)::placeholder {
  font-size: inherit;
}

/* ---- the phone top bar (lead, integration 2026-09-25) ----------------------
   The sound toggle joined the row, and at 360 to 440px the wordmark broke
   onto two lines in every set. Below 480px the wordmark keeps one line and a
   size the row can hold, and the top bar's Instagram link gives way to the
   round Instagram button that is already fixed in the corner of these pages;
   the proposal link may still stack into two lines. */
@media (max-width: 480px) {
  :where(.tsv-page) .topbar-brand {
    white-space: nowrap;
    font-size: min(var(--fs-wordmark), 15px);
    letter-spacing: min(var(--tracking-wordmark), 0.1em);
  }

  :where(.tsv-page) .topbar-in > .ig-link:not(.ig-fab) {
    display: none;
  }

  /* and the row keeps air between the wordmark and the proposal link */
  :where(.tsv-page) .topbar-in {
    column-gap: 14px;
  }
}

/* the narrowest phones (360 to 380px): a touch tighter, so the proposal link
   holds two lines rather than three */
@media (max-width: 380px) {
  :where(.tsv-page) .topbar-in {
    column-gap: 10px;
  }

  :where(.tsv-page) .topbar-link {
    font-size: 11px;
    letter-spacing: 0.04em;
  }

  /* sound.js sets the toggle 16px off the link; the gap already keeps it clear */
  .tsv-page .topbar-in > .sound-toggle {
    margin-left: 0;
  }
}
