/* Layoutics — design tokens
 * Hallmark · theme: custom (tuned) · vibe: "sharp, premium, ink on paper, unfussy"
 * axes: light / roman-serif / neutral
 * Every colour and font on this site resolves through a token in this file.
 */

/* ---- Faces, served from this site (2026-09-28; swapped 2026-09-29) ----
   Our origin, not Google Fonts / Fontshare: two outside stylesheets cost the
   phone ~2.2s to first paint on slow 4G. Latin and Latin Extended only; the
   Arabic face comes with the Arabic version. Licences in
   assets/fonts/LICENSES.txt.
   2026-09-29: the type is ToDesktop's (owner's call): Aeonik Pro 400/500 for
   headings, Inter (variable, 400-600) for text, Geist Mono for labels.
   Fraunces now sets only the wordmark: it is the logo, not the text face. */
@font-face {
  font-family: 'Aeonik Pro';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/aeonik-pro-400.woff2") format("woff2");
}
@font-face {
  font-family: 'Aeonik Pro';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/aeonik-pro-500.woff2") format("woff2");
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("assets/fonts/inter-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("assets/fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Caveat';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("assets/fonts/caveat-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("assets/fonts/fraunces-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("assets/fonts/geist-mono-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("assets/fonts/geist-mono-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;
}
/* BizArch's own faces, for its hand-built page in the hero film (2026-09-30).
   Loaded only when that page is on screen: nothing else uses them. */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500 700;
  font-display: swap;
  src: url("assets/fonts/space-grotesk-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/plex-arabic-500.woff2") format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("assets/fonts/plex-arabic-700.woff2") format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}

:root {
  /* ---- Type families — 2 + 1 (display · body · annotation outlier) ---- */
  --font-display: "Aeonik Pro", "Inter", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Inter", "Helvetica Neue", "Segoe UI", Arial, sans-serif;
  --font-brand: "Fraunces", "Iowan Old Style", Georgia, serif;   /* the wordmark only */
  --font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;
  /* Not part of the system — the system's foil. The spec-sheet specimens set
     the "generic" side in the browser default so the comparison is real type
     against real type, not our type against a greyed-out imitation of it. */
  --font-template: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* ---- Colour — neutral grey, neutral near-black ink, one ultramarine mark ----
     Was warm off-paper with a vermilion correction mark until 2026-09-28. The
     owner's brother: red reads as an alert on a screen, and it does. The grey
     is sampled from the owner's reference (#f1f1f1, a true neutral); ink and
     night went neutral with it, since warm ink on neutral grey reads brown.
     The blue is NOT the reference icon's periwinkle (#8fa3f9: the lavender-blue
     of every AI startup, and 2.1:1 as text) nor the stock app blue (#3a71f9,
     3.8:1): it is the deep end of the same hue, ultramarine, blueprint and
     fountain-pen ink. 5.6:1 on the grey. Red survives as --color-error only. */
  --color-paper:      oklch(95.8% 0     0);     /* #f1f1f1 */
  --color-paper-2:    oklch(93%   0     0);     /* #e8e8e8 */
  --color-paper-3:    oklch(91.6% 0     0);     /* #e3e3e3 */
  --color-ink:        #141414;                  /* ToDesktop's ink (2026-09-29) */
  --color-ink-2:      #656565;                  /* their secondary text: 5.2:1 on the grey */
  --color-muted:      oklch(50%   0.006 270);
  --color-neutral:    oklch(62%   0.005 270);
  --color-rule:       oklch(84%   0.003 270);
  --color-rule-2:     oklch(89.5% 0.002 270);
  --color-card:       oklch(100%  0     0);     /* white: the nav pill, raised on the grey */
  --color-pill:       oklch(93.5% 0     0);     /* the current section inside it: #ececec */
  --color-accent:     oklch(50%   0.200 268);   /* the mark: #3453d3 */
  --color-accent-deep:oklch(46%   0.190 266);   /* hover, and text on the accent: #2649c0 */
  --color-accent-ink: oklch(97%   0.005 270);
  --color-accent-light: oklch(74% 0.110 272);   /* the mark on the dark bands: #92a6f1, 7:1 on night */
  --color-focus:      oklch(50%   0.200 268);
  /* red is an alert, so it is only ever used as one: form errors, and the
     dashed underline on placeholders that must be filled before launch */
  --color-error:      oklch(55%   0.185 30);
  --color-error-night:oklch(70%   0.150 28);

  /* ---- ToDesktop's own greys (2026-09-29, the clone). Named so the dark
     theme can swap them; light values are theirs, measured. ---- */
  --t-ink:        #141414;                  /* titles, links, prices */
  --t-ink-2:      #656565;                  /* body text, subs */
  /* 2026-10-10 final check (owner's go): ToDesktop's #a4a4a4 measured 2.21:1
     on the footer's paper (headings, Email/WhatsApp/Office, the copyright);
     #6e6e6e is 4.51:1. UNDO: put #a4a4a4 back here and in the light block
     below (the dark theme's own value is unchanged). */
  --t-ghost:      #6e6e6e;                  /* labels, icons, the copyright */
  --t-well:       rgb(55 55 55 / 0.04);     /* pill eyebrows, pricing wells, chip links */
  --t-well-2:     rgb(55 55 55 / 0.05);     /* the segmented control */
  --t-well-hover: rgb(55 55 55 / 0.1);
  --t-line:       rgb(22 22 22 / 0.06);     /* hairlines, FAQ boxes, footer */
  --t-line-2:     rgb(22 22 22 / 0.04);
  --t-hover:      rgb(22 22 22 / 0.03);
  --t-dash:       rgb(22 22 22 / 0.12);     /* the pricing cards' dashed rule */
  --t-panel:      rgb(255 255 255 / 0.88);  /* the pricing cards' name panel */
  --t-pill:       rgb(255 255 255 / 0.88);  /* the floating nav pill */
  --t-open:       rgb(255 255 255 / 0.6);   /* an open FAQ answer's box */

  /* ---- Night — the same system read on ink. `.on-ink` remaps the colour
     tokens above to these, so every component inside a dark band inverts
     without a single per-component override. The accent becomes the light
     blue there, because the deep one sinks into near-black. ---- */
  --color-night-paper:   oklch(18%   0.006 270);
  --color-night-paper-2: oklch(21.5% 0.006 270);
  --color-night-paper-3: oklch(27%   0.006 270);
  --color-night-ink:     oklch(95.8% 0     0);
  --color-night-ink-2:   oklch(82%   0.004 270);
  --color-night-muted:   oklch(65%   0.005 270);
  --color-night-neutral: oklch(50%   0.005 270);
  --color-night-rule:    oklch(31%   0.006 270);
  --color-night-rule-2:  oklch(25%   0.006 270);

  /* ---- Glow — the accent at a strength that is felt, not seen. Twice on the
     page: behind the hero headline (day) and behind the form (night). ---- */
  --color-glow-day:   oklch(50% 0.200 268 / 0.06);
  --color-glow-night: oklch(60% 0.160 268 / 0.20);
  /* the form answers the hero: its glow, stronger, behind the heading */
  --color-glow-form:  oklch(55% 0.180 268 / 0.13);
  /* drawing-only: warm daylight in the "Show your work" sample room */
  --color-daylight:      oklch(80% 0.07 55);
  --color-daylight-deep: oklch(70% 0.10 45);
  --color-daylight-haze: oklch(80% 0.07 55 / 0.6);
  --color-clay:          oklch(62% 0.11 40);
  /* drawing-only: the "Take bookings" card is Rawda Spa's treatment room at
     dusk — sage plaster, dark stone, lamplight through a mashrabiya arch.
     The wall stays dark where the card's text sits (night-ink reads on it). */
  --color-spa-wall-top:  oklch(20% 0.014 150);
  --color-spa-wall:      oklch(31% 0.022 145);
  --color-spa-reveal:    oklch(40% 0.022 140);
  --color-spa-floor:     oklch(25% 0.014 60);
  --color-spa-floor-2:   oklch(15% 0.010 60);
  --color-spa-lamp-hi:   oklch(93% 0.05 85);
  --color-spa-lamp:      oklch(80% 0.11 70);
  --color-spa-lamp-deep: oklch(64% 0.13 50);
  --color-spa-lamp-haze: oklch(78% 0.11 65 / 0.34);
  --color-spa-lattice:   oklch(30% 0.03 55 / 0.62);
  --color-spa-linen:     oklch(93% 0.012 85);
  --color-spa-linen-2:   oklch(80% 0.016 80);
  --color-spa-sage:      oklch(60% 0.045 145);
  --color-spa-wood:      oklch(34% 0.035 55);
  --color-spa-stone:     oklch(47% 0.012 80);
  --color-spa-steam:     oklch(95% 0.01 85 / 0.16);
  /* drawing-only: "Offer services" — Sanad Advisory's office, morning, slate */
  --color-office-wall-top:  oklch(19% 0.014 250);
  --color-office-wall:      oklch(32% 0.020 245);
  --color-office-frame:     oklch(26% 0.016 245);
  --color-office-sun:       oklch(93% 0.04 85);
  --color-office-sky:       oklch(80% 0.05 230);
  --color-office-sun-haze:  oklch(88% 0.06 80 / 0.22);
  --color-office-slat:      oklch(22% 0.012 250 / 0.55);
  --color-office-floor:     oklch(30% 0.030 60);
  --color-office-floor-2:   oklch(17% 0.016 60);
  --color-office-oak:       oklch(50% 0.060 65);
  --color-office-oak-2:     oklch(38% 0.050 60);
  --color-office-leaf:      oklch(52% 0.070 140);
  --color-office-leaf-2:    oklch(33% 0.050 150);
  --color-office-pot:       oklch(72% 0.012 80);
  --color-office-lamp:      oklch(86% 0.10 78);
  /* drawing-only: "Sell online" — Qamra Coffee's bar, amber, fluted oak */
  --color-cafe-wall-top:    oklch(17% 0.020 55);
  --color-cafe-wall:        oklch(29% 0.045 58);
  --color-cafe-flute:       oklch(10% 0.02 50 / 0.18);
  --color-cafe-oak:         oklch(58% 0.080 65);
  --color-cafe-oak-2:       oklch(34% 0.050 55);
  --color-cafe-brass:       oklch(62% 0.090 80);
  --color-cafe-brass-2:     oklch(38% 0.060 70);
  --color-cafe-lamp:        oklch(90% 0.11 85);
  --color-cafe-lamp-haze:   oklch(80% 0.13 70 / 0.30);
  --color-cafe-glass:       oklch(80% 0.02 80 / 0.28);
  --color-cafe-bean:        oklch(30% 0.050 45);
  --color-cafe-bag:         oklch(22% 0.020 50);
  --color-cafe-cup:         oklch(94% 0.010 80);
  /* drawing-only: "Go mobile" — Riyadh at dusk */
  --color-dusk-sky-top:     oklch(19% 0.030 265);
  --color-dusk-sky:         oklch(31% 0.045 270);
  --color-dusk-glow:        oklch(52% 0.080 35);
  --color-dusk-horizon:     oklch(74% 0.110 62);
  --color-dusk-city:        oklch(15% 0.018 265);
  --color-dusk-window:      oklch(86% 0.10 80);
  --color-dusk-road:        oklch(14% 0.012 265);
  --color-dusk-road-2:      oklch(9%  0.008 265);
  --color-dusk-palm:        oklch(11% 0.012 220);
  --color-dusk-kerb:        oklch(30% 0.045 58 / 0.7);
  --color-dusk-pave:        oklch(15% 0.018 55);
  --color-dusk-kerb-edge:   oklch(36% 0.040 60 / 0.55);
  --color-dusk-spill:       oklch(70% 0.120 62 / 0.2);
  --color-dusk-head:        oklch(93% 0.060 85);
  /* drawing-only: "Built around your idea" — a planning room after hours,
     the client's pencil sketch, and Rasin's status colours */
  --color-plan-wall-top:    oklch(17% 0.018 130);
  --color-plan-wall:        oklch(30% 0.034 125);
  --color-plan-table:       oklch(60% 0.050 78);
  --color-plan-table-2:     oklch(42% 0.045 70);
  --color-plan-note:        oklch(87% 0.090 95);
  --color-plan-note-2:      oklch(85% 0.050 25);
  --color-plan-note-3:      oklch(87% 0.050 160);
  --color-plan-marker:      oklch(30% 0.020 250 / 0.55);
  --color-plan-paper:       oklch(97.5% 0.006 90);
  --color-plan-grid:        oklch(80% 0.040 235 / 0.45);
  --color-plan-graphite:    oklch(38% 0.008 260);
  --color-plan-chalk:       oklch(92% 0.010 95 / 0.75);
  --color-plan-pencil:      oklch(80% 0.130 88);
  --color-plan-wood:        oklch(82% 0.050 70);
  --color-plan-eraser:      oklch(72% 0.090 20);
  --color-plan-go:          oklch(93% 0.060 85);
  --color-plan-go-ink:      oklch(42% 0.090 65);
  --color-plan-done:        oklch(93% 0.040 150);
  --color-plan-done-ink:    oklch(40% 0.070 150);
  /* drawing-only: Darb, the app sample — its own saffron, the kerb and car of the pickup, iOS greys */
  --color-darb:             oklch(76% 0.150 72);
  --color-darb-deep:        oklch(55% 0.130 58);
  --color-darb-tint:        oklch(92% 0.050 80);
  --color-map-park:         oklch(89% 0.055 140);   /* now only the iced-drink tile on the menu */
  --color-pickup-sky-top:   oklch(34% 0.050 265);
  --color-pickup-sky-low:   oklch(64% 0.090 50);
  --color-pickup-wall:      oklch(86% 0.025 80);
  --color-pickup-awning:    oklch(95% 0.020 85);
  --color-pickup-glow-hi:   oklch(92% 0.090 88);
  --color-pickup-glow:      oklch(76% 0.130 65);
  --color-pickup-barista:   oklch(38% 0.050 50);
  --color-pickup-counter:   oklch(46% 0.060 55);
  --color-pickup-frame:     oklch(30% 0.020 60);
  --color-pickup-leaf:      oklch(42% 0.070 145);
  --color-pickup-pot:       oklch(58% 0.090 45);
  --color-pickup-pave:      oklch(58% 0.030 70);
  --color-pickup-road:      oklch(26% 0.014 265);
  --color-pickup-car:       oklch(98% 0.004 90);
  --color-pickup-car-edge:  oklch(70% 0.010 80);
  --color-pickup-glass:     oklch(34% 0.020 250);
  --color-ios-fill:         oklch(94.5% 0.004 80);
  --color-ios-label-2:      oklch(52% 0.010 260);
  --color-iph-frame:        oklch(24% 0.008 260);
  --color-iph-frame-2:      oklch(44% 0.010 260);
  /* drawing-only: BizArch ERP's own dashboard, drawn on the invoicing card */
  --color-bizarch:          oklch(50% 0.120 245);
  --color-bizarch-tint:     oklch(94% 0.030 240);
  --color-bizarch-side:     oklch(17% 0.020 260);
  --color-bizarch-side-ink: oklch(84% 0.010 260);
  --color-bizarch-up:       oklch(52% 0.120 155);
  /* drawing-only: "From invoice to ERP" — a contractor's desk at night */
  --color-desk-wall-top:    oklch(16% 0.012 200);
  --color-desk-wall:        oklch(26% 0.020 195);
  --color-desk-edge:        oklch(48% 0.070 55);
  --color-desk-walnut:      oklch(36% 0.060 50);
  --color-desk-walnut-2:    oklch(20% 0.035 45);
  --color-desk-hat-hi:      oklch(95% 0.12 100);
  --color-desk-hat:         oklch(84% 0.16 92);
  --color-desk-hat-2:       oklch(64% 0.14 80);
  --color-desk-paper:       oklch(93% 0.015 240);
  --color-desk-paper-2:     oklch(80% 0.025 240);
  --color-desk-blue:        oklch(50% 0.10 255);
  /* drawing-only: "Put AI on shift" — a night atmosphere (light, no props),
     and a WhatsApp-style chat (its layout and bubble colours, not its mark) */
  --color-night-sky-top:    oklch(17% 0.025 225);
  --color-night-sky:        oklch(24% 0.035 215);
  --color-night-sky-low:    oklch(20% 0.030 205);
  --color-night-glow:       oklch(64% 0.110 60 / 0.50);
  --color-night-glow-2:     oklch(55% 0.060 200 / 0.25);
  --color-night-frame:      oklch(14% 0.020 225);
  --color-night-out-top:    oklch(22% 0.040 250);
  --color-night-out:        oklch(30% 0.050 245);
  --color-night-out-low:    oklch(42% 0.060 55);
  --color-night-bokeh:      oklch(88% 0.10 80 / 0.85);
  --color-night-bokeh-2:    oklch(80% 0.06 220 / 0.7);
  --color-night-stone:      oklch(46% 0.015 80);
  --color-night-wood:       oklch(26% 0.030 55);
  --color-night-leaf:       oklch(24% 0.040 170);
  --color-night-leaf-2:     oklch(15% 0.030 180);
  --color-wa-bg:            oklch(93% 0.018 85);
  --color-wa-out:           oklch(94% 0.070 140);
  --color-wa-accent:        oklch(62% 0.150 150);
  --color-wa-accent-deep:   oklch(46% 0.120 150);

  /* ---- Third-party marks — the Saudi checkout on the store sample. These are
     the payment brands' own colours, set as type (not their logo files). ---- */
  --color-pay-apple:   oklch(0% 0 0);
  --color-pay-mada-1:  oklch(62% 0.13 240);
  --color-pay-mada-2:  oklch(72% 0.16 130);
  --color-pay-visa:    oklch(30% 0.14 270);
  --color-pay-mc-1:    oklch(58% 0.24 27);
  --color-pay-mc-2:    oklch(78% 0.17 65);
  --color-pay-stc:     oklch(33% 0.19 305);
  --color-pay-tabby:   oklch(88% 0.16 170);
  --color-pay-tamara-1:oklch(82% 0.10 45);
  --color-pay-tamara-2:oklch(72% 0.14 350);
  --color-pay-tamara-3:oklch(62% 0.15 300);


  /* ---- Space — 4 pt scale, named by role ---- */
  --space-3xs: 0.125rem;
  --space-2xs: 0.25rem;
  --space-xs:  0.5rem;
  --space-sm:  0.75rem;
  --space-md:  1rem;
  --space-lg:  1.5rem;
  --space-xl:  2.5rem;
  --space-2xl: 4rem;
  --space-3xl: 6rem;
  --space-4xl: 9rem;
  --page-gutter: clamp(1.25rem, 5vw, 4.5rem);
  --measure: 62ch;

  /* ---- Type scale — ToDesktop's, measured 2026-09-29 at 1280 and 375 ----
     Their steps: 11 · 12 · 14 · 16 · 24 · 36 · 48 · 64 · 74 px. The two
     display roles are fluid between their phone and laptop values. */
  --text-xs:   0.6875rem;  /* 11: mono pill labels */
  --text-sm:   0.75rem;    /* 12: meta */
  --text-nav:  0.875rem;   /* 14: nav, small body */
  --text-base: 1rem;       /* 16: body and lead */
  --text-md:   1rem;       /* 16: item titles, subs (their lead is 16/26) */
  --text-lg:   1.5rem;     /* 24: card and plan titles */
  --text-xl:   2.25rem;    /* 36 */
  --text-2xl:  3rem;       /* 48 */
  --text-3xl:  4rem;       /* 64 */
  --text-4xl:  4.625rem;   /* 74 */
  --text-display:   clamp(2.875rem, 4.2vw + 1.5rem, 4.625rem);   /* hero: 46 phone → 74 */
  --text-display-s: clamp(2.875rem, 4.2vw + 1.5rem, 4.625rem);
  --text-section:   clamp(2.625rem, 3vw + 1.6rem, 4rem);         /* section heads: 42 phone → 64 */

  /* ---- Tracking: Aeonik at -1.5% from 36px up, -1% below (their values) ---- */
  --track-display: -0.015em;
  --track-xl:      -0.015em;
  --track-lg:      -0.015em;
  --track-md:      -0.015em;
  --track-sm:      -0.01em;
  --track-xs:      -0.01em;

  /* ---- Leading: theirs. 74/84 · 64/72 · 48/52 · 24/32 · 16/26 ---- */
  --leading-display: 1.135;
  --leading-tight:   1.1;
  --leading-snug:    1.125;
  --leading-heading: 1.33;

  /* ---- Motion ---- */
  --ease-out:    cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in:     cubic-bezier(0.7, 0, 0.84, 0);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-micro: 120ms;
  --dur-short: 220ms;
  --dur-long:  420ms;
  /* the capability carousel's slide, measured off Squarespace's live carousel
     (~1s, slow start, fast middle, long settle) */
  --ease-glide: cubic-bezier(0.3, 0.1, 0.2, 1);   /* fitted to their samples: 10% · 39% · 83% · 97% at 12 · 25 · 52 · 78% of the time */
  --dur-glide:  1000ms;

  /* ---- Rules and radii — hairlines, near-square ---- */
  --rule-hair: 1px;
  --rule-bold: 2px;
  --radius-none: 0;
  /* Slight curves since 2026-09-28 (owner: "slight, not deep"); the site was
     square (2px) before. By role, not one size: */
  --radius-xs: 4px;    /* tags, and the small UI inside the drawings */
  --radius-sm: 6px;    /* chips */
  --radius-md: 8px;    /* buttons, arrows, focus outlines, monograms */
  --radius-lg: 12px;   /* cards and frames */
  --radius-pill: 999px;

  /* ---- Depth — one lift, for panels that float over a drawn interface
     (the capability cards). Warm ink, never grey-black. ---- */
  --shadow-float: 0 0.9rem 2rem -0.6rem oklch(17% 0.012 45 / 0.42), 0 0.15rem 0.4rem oklch(17% 0.012 45 / 0.18);

  /* ---- Depth — six named levels ---- */
  --z-base: 1;
  --z-raised: 10;
  --z-dropdown: 100;
  --z-sticky: 200;
  --z-modal: 400;
  --z-toast: 500;
  --z-tooltip: 600;
}

/* A true hairline, but only where the display can resolve one. At 1dppx a
   0.5px border rounds unpredictably — sometimes to zero — so the 1px default
   above stands on standard displays. */
@media (min-resolution: 2dppx) {
  :root { --rule-hair: 0.5px; }
}
/* ...and only at exactly 2x. On 3x phones (iPhones) 0.5px is 1.5 physical
   pixels, drawn as one: a third of a line in light grey, and wherever a
   box's edge falls between pixels it faded out, usually the bottom edge of
   every chip, field and card (owner, on an iPhone, 2026-09-29). 1px there
   is three physical pixels, the ordinary web line. */
@media (min-resolution: 2.5dppx) {
  :root { --rule-hair: 1px; }
}

/* ================================================= the dark theme (2026-09-29)
   The owner's plan: the night of ToDesktop's hero sky, carried down the page.
   <html data-theme="dark"> (set before first paint by the head script, from
   the visitor's choice or else their device setting) swaps the tokens; the
   light theme is the default above and stays the design of record. The
   night is our sky's top colour, a deep violet-black; surfaces are white
   glass on it, text white at three strengths, the blue lifted a step so it
   still reads on the dark. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --color-paper:      #0e0a19;
  --color-paper-2:    #151120;
  --color-paper-3:    #1c1828;
  --color-card:       #181424;
  --color-pill:       #241f31;
  --color-ink:        #ececf1;
  --color-ink-2:      #a6a4b1;
  --color-muted:      #8d8b99;
  --color-neutral:    #6f6d7b;
  --color-rule:       #2c2839;
  --color-rule-2:     #221e2e;
  --color-accent:     oklch(62% 0.190 268);
  --color-accent-deep:oklch(56% 0.200 266);
  --color-focus:      var(--color-accent-light);
  --color-error:      var(--color-error-night);
  --color-glow-day:   oklch(60% 0.160 268 / 0.10);
  --color-glow-form:  oklch(60% 0.160 268 / 0.16);

  --t-ink:        #ececf1;
  --t-ink-2:      #a6a4b1;
  --t-ghost:      #7f7d8b;
  --t-well:       rgb(255 255 255 / 0.04);
  --t-well-2:     rgb(255 255 255 / 0.05);
  --t-well-hover: rgb(255 255 255 / 0.1);
  --t-line:       rgb(255 255 255 / 0.08);
  --t-line-2:     rgb(255 255 255 / 0.06);
  --t-hover:      rgb(255 255 255 / 0.04);
  --t-dash:       rgb(255 255 255 / 0.14);
  --t-panel:      rgb(255 255 255 / 0.06);
  --t-pill:       rgb(22 17 34 / 0.82);
  --t-open:       rgb(255 255 255 / 0.05);   /* was the light 60% white on the night: the answers' light-grey text vanished on it (owner, 2026-10-06) */
}

/* The service cards stay in the light theme's colours (owner, 2026-09-30:
   the dark swap turned their drawings into a cheap colour invert, with
   logos, chart bars and labels losing contrast). Each card is already its
   own lit scene, and its drawings depict real products with light screens,
   so the light values are put back on the card and everything inside it
   renders exactly as in light. Keep this list in step with the dark block. */
:root[data-theme="dark"] .mcard {
  color-scheme: light;
  --color-paper:      oklch(95.8% 0     0);
  --color-paper-2:    oklch(93%   0     0);
  --color-paper-3:    oklch(91.6% 0     0);
  --color-card:       oklch(100%  0     0);
  --color-pill:       oklch(93.5% 0     0);
  --color-ink:        #141414;
  --color-ink-2:      #656565;
  --color-muted:      oklch(50%   0.006 270);
  --color-neutral:    oklch(62%   0.005 270);
  --color-rule:       oklch(84%   0.003 270);
  --color-rule-2:     oklch(89.5% 0.002 270);
  --color-accent:     oklch(50%   0.200 268);
  --color-accent-deep:oklch(46%   0.190 266);
  --color-focus:      oklch(50%   0.200 268);
  --color-error:      oklch(55%   0.185 30);
  --color-glow-day:   oklch(50% 0.200 268 / 0.06);
  --color-glow-form:  oklch(55% 0.180 268 / 0.13);

  --t-ink:        #141414;
  --t-ink-2:      #656565;
  --t-ghost:      #6e6e6e;                  /* was #a4a4a4 (see above) */
  --t-well:       rgb(55 55 55 / 0.04);
  --t-well-2:     rgb(55 55 55 / 0.05);
  --t-well-hover: rgb(55 55 55 / 0.1);
  --t-line:       rgb(22 22 22 / 0.06);
  --t-line-2:     rgb(22 22 22 / 0.04);
  --t-hover:      rgb(22 22 22 / 0.03);
  --t-dash:       rgb(22 22 22 / 0.12);
  --t-panel:      rgb(255 255 255 / 0.88);
  --t-pill:       rgb(255 255 255 / 0.88);
  --t-open:       rgb(255 255 255 / 0.6);
}
