/* Sedjem's website: one page in the app's own colours and type. site/DESIGN.md explains the choices, and
   tests/test_site.py checks that every colour here is one of the palette's. */


/* IBM Plex Sans, Plex Sans Arabic and Plex Mono, under the SIL Open Font License (fonts/OFL-IBM-Plex.txt). Each
   face covers only its own script, so Latin text never loads an Arabic file and the reverse, and the mono face is
   only for the commands in the downloads section. Arabic has 400 for reading, 500 for buttons, links and labels,
   and 600 for headings. */
@font-face {
  font-family: "IBM Plex Sans"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/ibm-plex-sans-latin-400-normal.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"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("fonts/ibm-plex-sans-latin-500-normal.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"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("fonts/ibm-plex-sans-latin-600-normal.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"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("fonts/ibm-plex-sans-latin-700-normal.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: 400; font-display: swap;
  src: url("fonts/ibm-plex-sans-arabic-arabic-400-normal.woff2") format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+200C-200E, U+FB50-FDFF, U+FE70-FEFC;
}
@font-face {
  font-family: "IBM Plex Sans Arabic"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("fonts/ibm-plex-sans-arabic-arabic-500-normal.woff2") format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+200C-200E, U+FB50-FDFF, U+FE70-FEFC;
}
@font-face {
  font-family: "IBM Plex Sans Arabic"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("fonts/ibm-plex-sans-arabic-arabic-600-normal.woff2") format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+200C-200E, U+FB50-FDFF, U+FE70-FEFC;
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/ibm-plex-mono-latin-400-normal.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;
}

/* Plex Sans's stand-in while it loads: the computer's Arial (Liberation Sans on Linux) drawn to Plex's width and
   line height, so the swap moves nothing. Measured in Chromium: the same width at 100%, and Plex's ascent and
   descent of 1025 and 275 per 1000. No Arabic face is common to Windows, macOS, Android and Linux, so the Arabic
   text has no such stand-in. */
@font-face {
  font-family: "Plex Sans Fallback";
  src: local("Arial"), local("Liberation Sans"), local("Arimo");
  size-adjust: 100%; ascent-override: 102.5%; descent-override: 27.5%; line-gap-override: 0%;
}

/* ---------- tokens: the app's light and dark themes (app/static/app.css), the brand's teal, and the type ramp in
   DESIGN.md's frontmatter ---------- */
:root {
  color-scheme: light dark;
  /* surfaces, from the page up: a tray holds a card */
  --bg: #f4f5f7;
  --tray: #eef0f3;
  --card: #ffffff;
  --sunken: #eef0f3;           /* the commands and the subtitles */
  /* ink, and greys as ink of less weight */
  --text: #18202b;
  --muted: #5f6b7a;
  --line: rgba(24, 32, 43, 0.12);
  --line-strong: rgba(24, 32, 43, 0.22);
  --hover: rgba(24, 32, 43, 0.06);
  --highlight: rgba(255, 255, 255, 0);  /* the lit top edge of a raised surface, in the dark theme */
  /* teal in three roles: a fill under white text, an ink for links, and a mark */
  --fill: #0e7c7b;             /* 5.0:1 under white */
  --fill-strong: #0a6362;
  --on-fill: #ffffff;
  --link: #0a6362;
  --mark: #0e7c7b;             /* Sedjem's words, the bars */
  --mark-wash: #e2f3f2;
  --wrong: #5f6b7a;            /* the other models' words, underlined as a spellchecker does */
  /* the speakers' names, in the app's colours. The app's orange, #d9480f, is 4.3:1 on the white card, short of the
     4.5:1 a name of this size needs, so Karim takes the app's darker orange (its --s7), 5.0:1 */
  --s1: #2563eb; --s2: #b45309; --s3: #7c3aed; --s4: #0f766e;
  --ear: #14a3a1;              /* the logo's ear, drawn as a line */
  --view-light: block;         /* of a view drawn for each theme, the one on show */
  --view-dark: none;

  --font-latin: "IBM Plex Sans", "Plex Sans Fallback", system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", sans-serif;
  --font-arabic: "IBM Plex Sans Arabic", "IBM Plex Sans", "Segoe UI", "Noto Sans Arabic", system-ui, sans-serif;
  --font: var(--font-latin);
  --mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

  /* the roles of type, for phones first; the Arabic page retunes them below */
  --fs-display: 30px;
  --fs-title: 26px;
  --fs-lede: 18px;
  --fs-body: 16px;
  --fs-small: 14px;
  --lh-display: 1.1; --lh-title: 1.2; --lh-lede: 1.5; --lh-body: 1.6; --lh-small: 1.45;
  --track-display: -0.02em; --track-title: -0.01em;
  --fs-table: var(--fs-body);  /* the measured numbers' cells */
  --fs-line: 18px;             /* the hero's transcript, the same on both pages */
  --fs-register: 24px;
  --fs-code: 14px;

  --margin: 16px;
  --gap: 16px;
  --section: 48px;             /* above each section's rule */
  --inset: 32px;               /* below it, above the heading */
  --measure: 36em;

  /* motion, in milliseconds: the transcript's lines arriving one after another. --motion is the one switch; the
     reader's reduced motion turns it to 0, and site.js reads all four */
  --motion: 1;
  --motion-start: 150;
  --motion-step: 280;
  --motion-row: 360;
  --motion-quick: 150;
}
@media (min-width: 370px) {
  :root { --fs-display: 34px; }
}
@media (min-width: 700px) {
  :root { --margin: 32px; --gap: 24px; --section: 64px; --inset: 48px; --fs-display: 52px; --fs-title: 32px; --fs-lede: 20px; }
}
@media (min-width: 1000px) {
  :root { --fs-register: 28px; }
}
@media (min-width: 1100px) {
  :root { --margin: 48px; --fs-display: 60px; }
}
@media (prefers-reduced-motion: reduce) {
  :root { --motion: 0; }
}

/* The Arabic page, and the Arabic half of the 404 page: Plex Sans Arabic first, its Latin words falling through to
   Plex Sans; a step larger, as Arabic letters sit smaller on the same size; taller lines for the ascenders,
   descenders and dots; no tracking at all; and a shorter measure for its narrower letters. */
html:lang(ar) {
  --font: var(--font-arabic);
  --fs-display: 32px;
  --fs-title: 28px;
  --fs-lede: 20px;
  --fs-body: 19px;
  --fs-small: 16px;
  --lh-display: 1.3; --lh-title: 1.3; --lh-lede: 1.7; --lh-body: 1.8; --lh-small: 1.7;
  --track-display: 0; --track-title: 0;
  --fs-table: var(--fs-small);  /* the table's Latin model names fit their column at Arabic's smaller step */
  --measure: 30em;
}
@media (min-width: 370px) {
  html:lang(ar) { --fs-display: 36px; }
}
@media (min-width: 700px) {
  html:lang(ar) { --fs-display: 56px; --fs-title: 36px; --fs-lede: 22px; }
}
@media (min-width: 1100px) {
  html:lang(ar) { --fs-display: 64px; }
}

/* The dark theme, when the system asks for it and the reader hasn't picked light with the header's button, or when
   the reader picked dark (site.js). One token set written twice, as a media query and an attribute can't share a
   block; the tests keep the two the same. Surfaces grow lighter as they rise, and a raised one has a lit top edge
   in place of a shadow. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0f1216;
    --tray: #161a20;
    --card: #1b2027;
    --sunken: #11151a;
    --text: #e6eaf0;
    --muted: #9aa5b3;
    --line: rgba(230, 234, 240, 0.12);
    --line-strong: rgba(230, 234, 240, 0.2);
    --hover: rgba(230, 234, 240, 0.06);
    --highlight: rgba(255, 255, 255, 0.05);
    --fill: #0e7c7b;
    --fill-strong: #0a6362;
    --on-fill: #ffffff;
    --link: #2bb3b0;
    --mark: #2bb3b0;
    --mark-wash: #123332;
    --wrong: #9aa5b3;
    --s1: #6ea0ff; --s2: #ff8f5c; --s3: #b794ff; --s4: #3fcfbf;
    --ear: #0e7c7b;            /* quieter on the dark page, so the headline leads */
    --view-light: none;
    --view-dark: block;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0f1216;
  --tray: #161a20;
  --card: #1b2027;
  --sunken: #11151a;
  --text: #e6eaf0;
  --muted: #9aa5b3;
  --line: rgba(230, 234, 240, 0.12);
  --line-strong: rgba(230, 234, 240, 0.2);
  --hover: rgba(230, 234, 240, 0.06);
  --highlight: rgba(255, 255, 255, 0.05);
  --fill: #0e7c7b;
  --fill-strong: #0a6362;
  --on-fill: #ffffff;
  --link: #2bb3b0;
  --mark: #2bb3b0;
  --mark-wash: #123332;
  --wrong: #9aa5b3;
  --s1: #6ea0ff; --s2: #ff8f5c; --s3: #b794ff; --s4: #3fcfbf;
  --ear: #0e7c7b;            /* quieter on the dark page, so the headline leads */
  --view-light: none;
  --view-dark: block;
}
:root[data-theme="light"] { color-scheme: light; }

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 var(--fs-body)/var(--lh-body) var(--font);
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
img { display: block; max-width: 100%; height: auto; }
/* a view drawn for each theme, an image apiece (the logo, the pictures of the app): only the one for the theme on
   show is drawn, and, as the pictures load lazily, fetched */
.view-light { display: var(--view-light); }
.view-dark { display: var(--view-dark); }
h1, h2, h3 { margin: 0; text-wrap: balance; }
p, li, dd, dt, th, td, figcaption, caption { text-wrap: pretty; }
p { margin: 0; }
figure { margin: 0; }
/* Arabic in its own face wherever it starts (the whole Arabic page, or a line on the English one), with its
   English words falling through to Plex Sans; and never letter-spaced */
[lang="ar"] { font-family: var(--font-arabic); }
:lang(ar) { letter-spacing: 0; }

a { color: var(--link); text-decoration-thickness: 1px; text-underline-offset: 0.22em; }
a:hover { text-decoration-thickness: 2px; }
:focus-visible { outline: 2px solid var(--mark); outline-offset: 3px; border-radius: 4px; }

.wrap { width: min(100% - 2 * var(--margin), 1200px); margin: 0 auto; }
.keep { white-space: nowrap; }
/* product names never break at their hyphens (whisper-medium, Nemotron-3-Diarization) */
span[translate="no"] { white-space: nowrap; }
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.skip {
  position: absolute; z-index: 10; top: 12px; inset-inline-start: 12px;
  padding: 12px 16px; border-radius: 999px; background: var(--card); color: var(--text);
  font-weight: 500; text-decoration: none; box-shadow: inset 0 0 0 1px var(--line-strong);
  transform: translateY(-200%);
}
.skip:focus { transform: none; }

/* three levels of words in each section: the claim, its lede, the body and the captions under them */
h1 { font-size: var(--fs-display); font-weight: 600; line-height: var(--lh-display); letter-spacing: var(--track-display); }
h2 { font-size: var(--fs-title); font-weight: 600; line-height: var(--lh-title); letter-spacing: var(--track-title); }
h3 { font-size: var(--fs-body); font-weight: 600; line-height: var(--lh-body); }
.lede, .lead { font-size: var(--fs-lede); line-height: var(--lh-lede); }
figcaption, caption { color: var(--muted); font-size: var(--fs-small); line-height: var(--lh-small); }

/* ---------- buttons: pills of one height, filled or drawn with an inset line so the two line up exactly ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 36px; padding: 0 16px; border: 0; border-radius: 999px;
  background: var(--card); color: var(--text); box-shadow: inset 0 0 0 1px var(--line-strong);
  font: 600 var(--fs-small)/1.2 var(--font); text-decoration: none; white-space: nowrap;
  transition: background-color calc(var(--motion-quick) * 1ms * var(--motion)) ease-out;
}
.btn:hover { background: var(--hover); text-decoration: none; }
.btn-primary, .btn-primary:hover { color: var(--on-fill); box-shadow: none; }
.btn-primary { background: var(--fill); }
.btn-primary:hover { background: var(--fill-strong); }
.btn-large { padding: 0 20px; font-size: var(--fs-body); }  /* the hero's: the same height, its words a step larger */
.btn:focus-visible { border-radius: 999px; }
/* a finger gets a target of 44 px however small the button looks */
@media (pointer: coarse) {
  .btn, .theme, .menu summary { min-height: 44px; min-width: 44px; }
}

/* ---------- header: from 700 px the links and the theme button in one row; on a phone the logo, a download and a
   menu that opens without JavaScript ---------- */
.site-header { display: flex; align-items: center; gap: 12px; padding: 12px 0; }
.brand { display: block; margin-inline-end: auto; padding: 8px 0; border-radius: 4px; }
.brand img { width: auto; height: 24px; }
.nav-wide, .theme-wide { display: none; }
.nav { display: flex; align-items: baseline; gap: 24px; margin: 0; padding: 0; list-style: none; }
.nav a, .menu-panel a {
  display: block; padding: 8px 0;
  color: var(--text); font-size: var(--fs-small); font-weight: 500; text-decoration: none;
}
.nav a:hover, .menu-panel a:hover { text-decoration: underline; text-decoration-thickness: 1px; }
/* the other page's link, in its own language and script: Arabic a step larger to look the same size */
.other-lang[lang="ar"] { font-size: 16px; }
.other-lang[lang="en"] { font-size: 14px; }
.get-short { min-height: 32px; padding: 0 14px; }
.menu { position: relative; }
.menu summary {
  display: grid; place-items: center; width: 36px; height: 36px; border-radius: 999px;
  color: var(--text); list-style: none; cursor: pointer;
}
.menu summary::-webkit-details-marker { display: none; }
.menu summary:hover, .menu[open] summary { background: var(--hover); }
.menu summary svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; }
.menu-panel {
  position: absolute; z-index: 20; top: calc(100% + 8px); inset-inline-end: 0; width: 264px; padding: 8px 16px;
  border-radius: 8px; background: var(--card);
  box-shadow: inset 0 0 0 1px var(--line), inset 0 1px 0 var(--highlight), 0 8px 24px rgba(15, 18, 22, 0.16);
}
.menu-panel ul { margin: 0; padding: 0; list-style: none; }
.menu-panel a { padding: 12px 0; }
.menu-panel li + li { border-top: 1px solid var(--line); }
@media (min-width: 700px) {
  .site-header { gap: 24px; padding: 24px 0; }
  .brand img { height: 28px; }
  .nav-wide { display: block; }
  .get-short, .menu { display: none; }
}

/* the theme button: each press switches to the other theme (site.js). Its icon is the theme on show, a sun on a
   light page and the app's moon on a dark one, drawn from the theme's tokens, so it follows the system's setting too
   while no theme is picked. It is there only when site.js is there to work it. In the header the icon's edge, not
   the button's, meets the end of the column; in the menu it carries its name. */
.theme {
  display: none; align-items: center; gap: 12px; padding: 0; border: 0; border-radius: 999px;
  background: none; color: var(--text); font: 500 var(--fs-small)/1.2 var(--font); cursor: pointer;
  transition: background-color calc(var(--motion-quick) * 1ms * var(--motion)) ease-out;
}
.theme-wide { justify-content: center; width: 36px; height: 36px; margin-inline-start: -12px; margin-inline-end: -8px; }
.theme-wide:hover { background: var(--hover); }
.theme:focus-visible { border-radius: 999px; }
.theme svg {
  flex: none; width: 20px; height: 20px;
  fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round;
}
/* the theme a press switches to, as the button's name says: a moon on a light page, a sun on a dark one */
.theme .icon-light { display: var(--view-dark); }
.theme .icon-dark { display: var(--view-light); }
.can-switch-theme .theme-menu {
  display: flex; justify-content: flex-start; width: 100%; min-height: 44px; margin-top: 4px; padding: 8px 0;
  border-top: 1px solid var(--line); border-radius: 0; text-align: start;
}
@media (min-width: 700px) {
  .can-switch-theme .theme-wide { display: inline-flex; }
}

/* ---------- hero: the words on eight columns and the ear in the last three, both from the headline's top; the
   transcript across the column under them. Under 1000 px the ear is smaller and above the words, on the end side,
   and the transcript follows the words.
   ---------- */
.hero { padding: 24px 0 var(--section); }
.hero-grid { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: 32px; }
.lead { max-width: var(--measure); margin-top: 20px; color: var(--text); }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 24px; margin-top: 32px; }
.others { font-size: var(--fs-small); font-weight: 500; }
/* the brand icon's own ear, a thin line, unflipped on the Arabic page, where its place mirrors: here over the
   headline, one row gap above it, its end on the column's end, so the headline keeps its whole measure */
.ear {
  display: block; order: -1; justify-self: end;
  width: auto; height: 96px; fill: none; stroke: var(--ear); stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}
.ear path { vector-effect: non-scaling-stroke; }
@media (min-width: 700px) {
  .hero { padding-top: 40px; }
}
@media (min-width: 1000px) {
  .hero-grid { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: 48px; }
  .hero-text { grid-column: 1 / span 8; grid-row: 1; padding-inline-end: var(--gap); }
  /* beside the headline: its top level with the headline's and its end on the column's end */
  .ear { order: 0; grid-column: 10 / -1; grid-row: 1; align-self: start; height: 320px; }
  .hero-figure { grid-column: 1 / -1; grid-row: 2; }
  /* across the column, the transcript on eight parts and its export on the four beside it, read after it */
  .hero-figure .frame { display: grid; grid-template-columns: minmax(0, 8fr) minmax(0, 4fr); gap: 4px; }
  .hero-figure .srt { margin: 0; }
}

/* ---------- one frame for everything drawn by the app: a tray of translucent ink with a lit edge, 4 px around a
   card or a picture; the tray's corners are the card's plus that 4 px ---------- */
.frame {
  padding: 4px; border-radius: 8px; background: var(--tray);
  box-shadow: inset 0 0 0 1px var(--line), inset 0 1px 0 var(--highlight);
}
.frame img { border-radius: 4px; background: var(--card); }

/* the transcript: an app's card of lines, right to left on both pages, each time on the start edge and the speaker
   over the line, as the app lays them out */
.log { margin: 0; padding: 8px 4px; list-style: none; border-radius: 4px; background: var(--card); box-shadow: inset 0 1px 0 var(--highlight); }
.row { display: grid; grid-template-columns: 44px minmax(0, 1fr); column-gap: 12px; padding: 10px 12px; }
.ts { grid-row: 1 / span 2; padding-top: 2px; color: var(--muted); font: 400 var(--fs-small)/1.5 var(--mono); font-variant-numeric: tabular-nums; }
/* each name in its speaker's colour and bold, as the app shows it; every colour is 4.5:1 or more on the card */
.who { color: var(--c); font-size: var(--fs-small); font-weight: 600; line-height: 1.5; }
.say { margin: 2px 0 0; font-size: var(--fs-line); line-height: 1.65; text-align: start; }
/* the line that starts in English hangs from the same edge as the Arabic ones */
.say-ltr { text-align: end; }
.say span[lang="en"], .register mark { white-space: nowrap; }
/* the lines arrive one after another (site.js); until then each waits unseen, and without JavaScript or with less
   motion asked for, they are all simply there */
.will-reveal .log .row { opacity: 0; }

/* under it, in the same frame, the first line as the app exports it */
.srt {
  margin: 4px 0 0; padding: 12px 16px; border-radius: 4px; background: var(--card); box-shadow: inset 0 1px 0 var(--highlight);
  color: var(--text); font: 400 var(--fs-code)/1.6 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere;
}
.srt-name { color: var(--muted); }
/* on a phone the export's lines would wrap raggedly in its narrow box, so it is left out there, and so are the
   caption's words about it */
@media (max-width: 699px) {
  .srt, .with-srt { display: none; }
}
.srt span[lang="ar"] { font-family: var(--font-arabic); }
.hero-figure figcaption { margin-top: 12px; }

/* ---------- sections: a rule between them, then one row: the claim on five columns, its proof on the seven beside
   it, the caption under the proof at one offset ---------- */
.sec { padding-top: var(--section); }
.sec-grid { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: 32px; padding-top: var(--inset); border-top: 1px solid var(--line); }
.claim .lede { max-width: var(--measure); margin-top: 16px; }
.claim p:not(.lede) { max-width: var(--measure); margin-top: 12px; }
.claim .docs { margin-top: 16px; font-size: var(--fs-small); font-weight: 500; }
.proof figcaption, .proof caption { margin-top: 12px; }
@media (min-width: 1000px) {
  .sec-grid { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: 48px; align-items: start; }
  .claim { grid-column: 1 / span 5; padding-inline-end: var(--gap); }
  .proof { grid-column: 6 / -1; }
}

/* the registers: one line written two ways between rules. The other models' words are underlined in slate with a
   wave, as a spellchecker marks a word; Sedjem's own are set on a teal wash with a teal line */
.registers dl { margin: 0; border-bottom: 1px solid var(--line); }
.register { padding: 24px 16px; border-top: 1px solid var(--line); }
.register dt { color: var(--muted); font-size: var(--fs-small); font-weight: 500; }
.register dd { margin: 8px 0 0; font-size: var(--fs-register); line-height: 1.6; }
/* each half of the line its own block, so the two registers break alike and a narrow screen balances each half */
.register dd > span { display: block; text-wrap: balance; }
mark {
  padding: 0 2px; border-radius: 2px; background: var(--mark-wash); color: inherit;
  text-decoration: underline solid var(--mark) 2px; text-underline-offset: 0.42em; text-decoration-skip-ink: none;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
.register-off mark {
  padding: 0; background: none;
  text-decoration: underline wavy var(--wrong) 1.5px; text-underline-offset: 0.36em;
}

/* the measured numbers: one line of column names over their direction, tabular figures, the default marked, and a
   thin bar beside the English kept, which is the claim, growing from the column's start */
.results { width: 100%; border-collapse: collapse; font-size: var(--fs-table); font-variant-numeric: tabular-nums; }
.results caption { caption-side: bottom; text-align: start; }
.results th, .results td {
  padding: 12px 0; padding-inline-start: 16px; border-bottom: 1px solid var(--line);
  font-weight: 400; text-align: start; vertical-align: baseline;
}
.results th:first-child { padding-inline-start: 0; }
.results thead th {
  padding-top: 0; border-bottom-color: var(--line-strong); vertical-align: bottom;
  font-size: var(--fs-small); font-weight: 600; white-space: nowrap;
}
.results .hint { display: block; color: var(--muted); font-weight: 400; white-space: normal; }
.results abbr { text-decoration: none; }
.results .num { text-align: end; }
.results .kept, .results td.time { text-align: start; white-space: nowrap; }
.results .fig { font-family: var(--mono); font-size: var(--fs-small); }
.results .model { font-weight: 500; }
.results .note { display: block; color: var(--muted); font-size: var(--fs-small); }
.pill {
  /* inline, not a block of its own, so the no-break space before it keeps it with the model's last word */
  display: inline; margin-inline-start: 2px; padding: 1px 8px; border-radius: 999px;
  box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--muted);
  font-size: var(--fs-small); font-weight: 500; line-height: 1.5; white-space: nowrap;
}
.bar {
  position: relative; display: inline-block; width: 64px; height: 6px; margin-inline-end: 8px;
  border-radius: 999px; background: var(--line); vertical-align: middle;
}
.bar::before {
  content: ""; position: absolute; inset-block: 0; inset-inline-start: 0; width: calc(var(--v) * 1%);
  border-start-start-radius: 999px; border-end-start-radius: 999px; border-start-end-radius: 4px; border-end-end-radius: 4px;
  background: var(--mark);
}
.results .label { display: none; }
/* in Arabic every column reads from its start, the right; the figures, all of a width, line up on their points */
html:lang(ar) .results .num { text-align: start; }
@media (max-width: 699px) {
  /* one block per model; the roles in the markup keep it a table for screen readers, and the caption stays under */
  .results { display: flex; flex-direction: column; }
  .results tbody, .results tr, .results th, .results td { display: block; }
  .results caption { display: block; order: 2; margin-top: 16px; }
  .results thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .results tr { padding: 16px 0 12px; border-bottom: 1px solid var(--line); }
  .results th[scope="row"] { padding: 0 0 8px; border: 0; }
  .results td { display: flex; align-items: center; gap: 12px; padding: 4px 0; border: 0; }
  .results .label { display: inline; flex: 1; color: var(--muted); }
  .results .num, html:lang(ar) .results .num { text-align: start; }
}

/* the pictures of the app, at their own size, which is the app's: taken at two or three times it, and never drawn
   smaller, so no line of the app is shown smaller than the app draws it. The desktop form is up to 656 px wide and
   the phone form, below 750 px, up to 280, which a 320 px phone holds. The width and height in the markup (the phone
   form's on its sources) hold the place before a picture arrives, so nothing moves when it does. */
.shot .frame { width: fit-content; max-width: 100%; }
/* where seven columns are narrower than the desktop form, its section stacks, the claim over the picture, so the
   picture keeps its size */
@media (min-width: 1000px) and (max-width: 1279px) {
  .sec-shot .claim, .sec-shot .proof { grid-column: 1 / -1; }
  .sec-shot { row-gap: 32px; }
}

/* the facts: a spec sheet on a tonal plate, what Sedjem needs on the computer beside what it does with the
   recordings, each term over its value, and the licence across the foot */
.spec {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 32px 24px; padding: 24px 16px;
  border-radius: 8px; background: var(--tray);
}
.spec h3 { padding-bottom: 8px; border-bottom: 1px solid var(--line-strong); }
.spec dl { margin: 0; }
.spec dl div { margin-top: 16px; }
.spec dt { color: var(--muted); font-size: var(--fs-small); line-height: var(--lh-small); }
.spec dd { margin: 4px 0 0; }
.spec-foot { padding-top: 16px; border-top: 1px solid var(--line); }
.spec .spec-foot div { margin-top: 0; }
@media (min-width: 700px) {
  .spec { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 32px; }
  .spec-foot { grid-column: 1 / -1; }
}

/* ---------- the downloads ---------- */
.get { scroll-margin-top: 24px; }
.get .fine { margin-top: 12px; color: var(--muted); font-size: var(--fs-small); }
.way { margin-top: 32px; }
.proof > .way:first-child { margin-top: 0; }
.way p { max-width: var(--measure); margin-top: 8px; }
.way .btn { margin-top: 16px; }
.way .docs { font-size: var(--fs-small); font-weight: 500; }
@media (min-width: 1000px) {
  .get .proof > .way:first-child { margin-top: 0; }
}
/* the commands scroll sideways rather than break a word; the box takes the keyboard's focus for that, and its end
   edge fades the commands out while more of them is to the side. The fade covers the box's end padding only, so at
   the end of the scroll, or where the commands fit, nothing is faded. The ground and the line are the box around it,
   which the fade leaves whole. */
.code-box { margin: 12px 0 0; border-radius: 4px; background: var(--sunken); box-shadow: inset 0 0 0 1px var(--line); }
.code {
  margin: 0; padding: 16px 32px 16px 20px; overflow-x: auto; border-radius: 4px; color: var(--text); white-space: pre;
  font: 400 var(--fs-code)/1.75 var(--mono); tab-size: 2;
  -webkit-mask-image: linear-gradient(to left, transparent, var(--text) 32px);
  mask-image: linear-gradient(to left, transparent, var(--text) 32px);
}
/* the fade would hide the box's own focus ring, so the ring goes on the box around it */
@supports selector(:has(*)) {
  .code:focus-visible { outline: none; }
  .code-box:has(> .code:focus-visible) { outline: 2px solid var(--mark); outline-offset: 3px; }
}

/* ---------- footer ---------- */
.site-footer { padding: var(--section) 0 64px; }
.foot { font-size: var(--fs-small); line-height: var(--lh-small); }
.name-note { max-width: 26em; color: var(--text); font-size: var(--fs-body); line-height: var(--lh-body); }
.foot-meta p { margin-top: 12px; color: var(--muted); }
.foot-links { display: flex; flex-wrap: wrap; gap: 4px 24px; margin: 0; padding: 0; list-style: none; }
.foot-links a { display: block; padding: 4px 0; color: var(--text); font-weight: 500; text-decoration: none; }
.foot-links a:hover { text-decoration: underline; }

/* ---------- forced colours: borders the theme drew with shadows ---------- */
@media (forced-colors: active) {
  .frame, .btn, .srt, .code-box, .menu-panel, .spec { border: 1px solid CanvasText; }
  .bar::before { background: CanvasText; }
}
