/* MobiCAM website — brand tokens (graphite + amber, Jost / Space Mono), light + dark.
   No inline styles anywhere → the CSP can forbid 'unsafe-inline'. */

/* Fonts are self-hosted (same woff2 files the desktop app ships) — no Google Fonts request, so
   `font-src`/`style-src` stay 'self' and the site renders identically with no third party reachable.
   Jost is a VARIABLE font (`font-weight: 400 700`): these two files cover the 400/500/600/700 the
   page asks for. Split by unicode-range so Turkish (ı ş ğ) pulls latin-ext only when needed. */

/* latin-ext */
@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(fonts/Jost-400-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;
}
/* latin */
@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(fonts/Jost-400-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;
}
/* latin-ext */
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/SpaceMono-400-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;
}
/* latin */
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(fonts/SpaceMono-400-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;
}
/* latin-ext */
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/SpaceMono-700-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;
}
/* latin */
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/SpaceMono-700-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;
}

:root {
  --bg: #ece7de; --surface: #fbf8f2; --surface-2: #ffffff;
  --ink: #17140f; --ink-soft: #6a6155;
  --line: rgba(23, 20, 15, .13); --line-strong: rgba(23, 20, 15, .2);
  /* Three amber tokens, because the amber does three jobs and only one value fits each. `--acc` is
   * the **fill** (buttons, ticks, rules, the logotype) and stays the brand colour exactly. `--on-acc`
   * is what sits **on** that fill: white measured 3.85:1 against it, dark ink measures 4.90, so the
   * label is dark here and the amber is untouched. `--acc-ink` is the amber **as type** — the same
   * hue taken down to where 12 px of it reads on paper, since `--acc` itself measured 3.12 on the
   * page background. Measured by `deploy/audit-contrast.mjs`; the app carries the same three. */
  --acc: #b4741f; --on-acc: #14110c; --acc-ink: #8a5312; --grid: rgba(23, 20, 15, .05);
  --dark-bg: #14110c;
  --geo: "Jost", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Space Mono", ui-monospace, Menlo, Consolas, monospace;
  --wrap: 1240px;
  color-scheme: light;
}

/* ============================================================================
   TYPE — the scale, and the metrics that belong to each step

   `status-design-critique.md`'s verdict on this site was "the archetype is not
   wrong; having a single SCALE is". It applied that to two headings and stopped.
   This is the rest of it — every heading, and the metrics nobody had counted.
   (`status-tone.md` separately owes the APP a metrics pass. Not this file.)

   What it found. The site was running on THIRTY-SEVEN type sizes — 25 fixed, ten
   fluid ramps and two relative — across styles.css, kilavuz.css and portal.css.
   Between 9.5 and 17 px it was not a scale but a continuum: 9.5, 10, 10.5, 11,
   11.5, 12, 12.5, 13, 13.5, 14, 14.5, 15, 16, 16.5, 17. Fifteen rungs inside
   seven and a half pixels is fifteen separate decisions, none of which anybody
   could take the same way twice — which is how a card heading came to be set
   0.5 px above the paragraph under it, and a manual's h4 1.5 px BELOW its own.

   Two ramps, because a page has two jobs and one ratio cannot do both.

   DISPLAY is geometric: 64 px stepped down by ×1.2. The site was already
   close — 64, 50, 44, 38, 31, 26, 21 against the ratio's 64, 53, 44, 37, 31,
   26, 21 — and had drifted off at exactly two rungs. Those two move.

   TEXT is arithmetic, 11–16 px in whole pixels, because legibility at reading
   size is not proportional: 13 and 14 px are different jobs and a 1.2 ratio
   cannot tell them apart. The floor is 11. The 9.5 px `.badge-soon` and the
   10 px `.plan-pop` were smaller than anything this site should set at all.

   The ramps meet at 18 px — the display ramp's bottom rung, one step above the
   text ramp's top.

   Whole pixels only. The half-pixel is what produced the continuum; nothing
   here rounds to .5, and `deploy/audit-type.mjs` fails the build if one appears
   anywhere in the three stylesheets.
   ============================================================================ */
:root {
  /* text — arithmetic. Chrome, labels, table cells, paragraphs. */
  --fs-t1: 11px; --fs-t2: 12px; --fs-t3: 13px;
  --fs-t4: 14px; --fs-t5: 15px; --fs-t6: 16px;

  /* display — 64px ÷ 1.2ⁿ, rounded to whole pixels. Ideal: 64, 53.33, 44.44,
     37.04, 30.86, 25.72, 21.43, 17.86 — the worst rounding here is 0.44px. */
  --fs-d1: 18px; --fs-d2: 21px; --fs-d3: 26px; --fs-d4: 31px;
  --fs-d5: 37px; --fs-d6: 44px; --fs-d7: 53px; --fs-d8: 64px;

  /* Mono set inside running text. Space Mono's advance is 0.6em against Jost's
     ~0.5em, so the same px reads larger; one value, not the .84/.86 the manual
     was using for `kbd` and `code` — which are the same thing. */
  --fs-mono-inline: .86em;

  /* ── The six ranks ────────────────────────────────────────────────────────
     The critique's verdict was "the archetype is not wrong; having a single
     SCALE is" — meaning a heading's size was following its TAG rather than its
     job. `.lead` and `:has(+ .spec-wrap)` answered that for two headings. These
     answer it for all six, and are what the rest of this file sets a heading to.

     Each rank is a three-rung window on the display ramp, and each sits exactly
     one rung below the rank above it AT BOTH ENDS. That second half is the part
     that was missing: five of the ten ramps floored at exactly 30 px, so on any
     phone a page title, a page's claim and a section heading came out the same
     size — the hierarchy existed only on a desktop. Now it holds at 320 px.

     The vw coefficients are picked so all six leave their floor at ~820 px and
     reach their ceiling at ~1185 px. They used to top out anywhere between
     933 px (the closing CTA) and 1192 px (a module row), so between those two
     widths the ranks genuinely reordered against each other as you resized. */
  --fs-hero:     clamp(var(--fs-d6), 5.4vw, var(--fs-d8));  /* the home page's one statement */
  --fs-title:    clamp(var(--fs-d5), 4.5vw, var(--fs-d7));  /* a page title */
  --fs-claim:    clamp(var(--fs-d4), 3.7vw, var(--fs-d6));  /* the page's claim — used once */
  --fs-section:  clamp(var(--fs-d3), 3.1vw, var(--fs-d5));  /* an inventory heading */
  --fs-argument: clamp(var(--fs-d2), 2.6vw, var(--fs-d4));  /* one argument, in one row */
  --fs-label:    clamp(var(--fs-d1), 2.2vw, var(--fs-d3));  /* a heading that introduces a table */

  /* ── Metrics ──────────────────────────────────────────────────────────────
     Eleven leadings and twelve trackings, for what is two rules: leading opens
     and tracking loosens as the type gets smaller, and a mono label is
     letterspaced. Seven and five, each used by more than one role. */
  --lh-display: 1.05;  /* hero, page title */
  --lh-head: 1.1;      /* claim, section */
  --lh-sub: 1.2;       /* argument, table label */
  --lh-lede: 1.35;     /* ledes, card titles — the d1/d2 rungs set at a fixed size */
  --lh-ui: 1.5;        /* chrome, table cells, anything that is not a paragraph */
  --lh-read: 1.6;      /* a paragraph */
  --lh-long: 1.7;      /* the manual's 76ch column, read line by line rather than scanned */

  --tr-display: -.03em;  /* d7–d8 */
  --tr-head: -.02em;     /* d5–d6 */
  --tr-sub: -.015em;     /* d3–d4 */
  --tr-small: -.01em;    /* d1–d2 */
  --tr-label: .04em;     /* a mono label */
  --tr-eyebrow: .14em;   /* a mono eyebrow */
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #14110c; --surface: #1d1810; --surface-2: #231d14;
    --ink: #f1ece4; --ink-soft: #b0a693;
    --line: rgba(255, 255, 255, .14); --line-strong: rgba(255, 255, 255, .22);
    --acc: #e39a3a; --on-acc: #17140f; --acc-ink: #e39a3a; --grid: rgba(255, 255, 255, .05);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #14110c; --surface: #1d1810; --surface-2: #231d14;
  --ink: #f1ece4; --ink-soft: #b0a693;
  --line: rgba(255, 255, 255, .14); --line-strong: rgba(255, 255, 255, .22);
  --acc: #e39a3a; --on-acc: #17140f; --acc-ink: #e39a3a; --grid: rgba(255, 255, 255, .05);
  color-scheme: dark;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--geo); font-size: var(--fs-t6); line-height: var(--lh-ui);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--acc-ink); text-decoration: none; }
::selection { background: var(--acc); color: var(--on-acc); }
/* The default tracking for a heading that has not been given a rank; every ranked heading below
   overrides it with the tracking its own rung is worth. The default suits an h2, which is the
   section rank. An h3 on this site is never bigger than d2 — a card title, a step, a chain stage —
   and the system loosens tracking as the rank descends, so it takes the small one. */
h1, h2, h3 { margin: 0; letter-spacing: var(--tr-head); text-wrap: balance; }
h3 { letter-spacing: var(--tr-small); }
p { margin: 0; }
img, svg { display: block; }
:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; border-radius: 4px; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding-left: 30px; padding-right: 30px; }
.mono { font-family: var(--mono); }
.muted { color: var(--ink-soft); }
.strong { font-weight: 700; }
.acc { color: var(--acc-ink); }
.ink { color: var(--ink); }
.skip { position: absolute; left: -999px; top: 0; background: var(--acc); color: var(--on-acc); padding: 10px 16px; z-index: 200; }
.skip:focus { left: 12px; top: 12px; }

/* ---- buttons ---- */
.btn {
  display: inline-flex; align-items: center; gap: 9px; cursor: pointer;
  font-family: var(--geo); font-weight: 600; font-size: var(--fs-t4);
  padding: 10px 18px; border-radius: 10px; border: 1px solid transparent;
  transition: filter .14s ease, background .14s ease, border-color .14s ease;
}
.btn svg { width: 16px; height: 16px; }
.btn-lg { font-size: var(--fs-t6); padding: 15px 26px; border-radius: 11px; }
.btn-block { width: 100%; justify-content: center; margin-top: 4px; padding: 13px; font-size: var(--fs-t5); }
.btn-primary { background: var(--acc); color: var(--on-acc); }
.btn-primary:hover { filter: brightness(1.06); }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn-ghost:hover { border-color: var(--line-strong); }
.btn-ghost-dark { background: rgba(255, 255, 255, .08); color: #f1ece4; border-color: rgba(255, 255, 255, .2); }
.btn-ghost-dark:hover { background: rgba(255, 255, 255, .14); }

/* ---- header ---- */
.site-header {
  position: sticky; top: 0; z-index: 80;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(12px); border-bottom: 1px solid var(--line);
}
.header-inner { display: flex; align-items: center; gap: 30px; padding-top: 14px; padding-bottom: 14px; }
.brand { display: inline-flex; align-items: center; gap: 11px; color: var(--ink); }
.brand-mark { width: 32px; height: 32px; }
.brand-mark.sm { width: 28px; height: 28px; }
.mark-stitch { stroke: var(--acc); }
.brand-word { font-weight: 600; font-size: var(--fs-d2); letter-spacing: var(--tr-small); }
/* The wordmark keeps the brand amber where `.acc` elsewhere takes the readable one. Two reasons and
   both matter: WCAG 1.4.3 exempts a brand name by name, and the mark beside it is the same amber —
   a wordmark half a shade off its own logo is a worse defect than the one being fixed. The
   `data-logotype` attribute is how `deploy/audit-contrast.mjs` is told, rather than it guessing. */
[data-logotype] .acc { color: var(--acc); }
.brand-word.sm { font-size: var(--fs-d1); }
.nav { display: flex; gap: 26px; margin-left: 8px; }
.nav a { color: var(--ink-soft); font-weight: 500; font-size: var(--fs-t4); }
.nav a:hover { color: var(--ink); }
.header-actions { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.icon-btn {
  width: 38px; height: 38px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--line); border-radius: 9px; cursor: pointer; color: var(--ink); padding: 0;
}
.icon-btn svg { width: 17px; height: 17px; }
.link-login { color: var(--ink); font-weight: 600; font-size: var(--fs-t4); }

/* Visually hidden, still read aloud. The theme buttons are icon-only; without these they announce
   as "button" three times. `clip-path` rather than `display:none`, which removes them from the
   accessibility tree entirely.
   The label is absolutely positioned, so it needs a positioned ancestor — without one it anchors to
   the page and `white-space: nowrap` pushes "Sistem"/"Koyu" out past the right edge of a 320 px
   viewport. That is a real sideways scroll, and the layout audit caught it: +27.9px, span.vh. */
.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ---- theme: Sistem / Açık / Koyu ----
   Same shell as .lang-toggle so the two controls read as one family. Three states because a
   two-state toggle has no way back: once a visitor pressed it they were pinned to an explicit theme
   for good, with no way to return to following their device. */
.seg { display: inline-flex; align-items: center; gap: 2px; height: 38px; padding: 3px; background: var(--surface); border: 1px solid var(--line); border-radius: 9px; }
.seg button {
  position: relative;   /* containing block for the .vh label — see the note there */
  border: none; cursor: pointer; border-radius: 6px; width: 30px; height: 30px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--ink-soft);
  transition: background .14s ease, color .14s ease;
}
.seg button svg { width: 16px; height: 16px; }
.seg button[aria-checked="true"] { background: var(--acc); color: var(--on-acc); }
.seg button:hover[aria-checked="false"] { color: var(--ink); }
.lang-toggle { display: inline-flex; align-items: center; gap: 2px; height: 38px; padding: 3px; background: var(--surface); border: 1px solid var(--line); border-radius: 9px; }
/* The control is a pair of buttons on a Turkish-only site and a pair of links once /en/ ships
   (deploy/site/site.config.json → "en"). Both must look identical, so the rules name both. */
.lang-toggle button, .lang-toggle a {
  border: none; cursor: pointer; border-radius: 6px; padding: 0 9px; height: 30px;
  display: inline-flex; align-items: center; text-decoration: none;
  font-family: var(--mono); font-weight: 700; font-size: var(--fs-t2); letter-spacing: var(--tr-label);
  background: transparent; color: var(--ink-soft);
  transition: background .14s ease, color .14s ease;
}
.lang-toggle button.on, .lang-toggle a.on { background: var(--acc); color: var(--on-acc); }
.lang-toggle button:hover:not(.on), .lang-toggle a:hover:not(.on) { color: var(--ink); }

/* ---- hero ---- */
.grid-bg { background-image: linear-gradient(var(--grid) 1px, transparent 1px), linear-gradient(90deg, var(--grid) 1px, transparent 1px); background-size: 28px 28px; }
.hero-inner { display: grid; grid-template-columns: 1.02fr .98fr; gap: 56px; align-items: center; padding-top: 74px; padding-bottom: 40px; }
.eyebrow { display: inline-flex; align-items: center; gap: 9px; font-family: var(--mono); font-weight: 700; font-size: var(--fs-t1); letter-spacing: var(--tr-eyebrow); color: var(--acc-ink); }
.tick { width: 7px; height: 7px; background: var(--acc); display: block; }
h1 { font-weight: 700; font-size: var(--fs-hero); line-height: var(--lh-display); margin-top: 22px; letter-spacing: var(--tr-display); }
.lede { font-size: var(--fs-d1); line-height: var(--lh-read); color: var(--ink-soft); margin-top: 22px; max-width: 520px; text-wrap: pretty; }
.hero-cta { display: flex; gap: 13px; margin-top: 32px; flex-wrap: wrap; }
.hero-cta.center { justify-content: center; }
.hero-note { margin-top: 20px; font-family: var(--mono); font-size: var(--fs-t2); color: var(--ink-soft); }
.hero-media { position: relative; }
.app-frame { position: relative; margin: 0; background: var(--surface); border: 1px solid var(--line); box-shadow: 0 40px 80px -44px rgba(23, 20, 15, .5); }
.corner { position: absolute; width: 14px; height: 14px; }
.corner.tl { top: -1px; left: -1px; border-top: 2px solid var(--acc); border-left: 2px solid var(--acc); }
.corner.tr { top: -1px; right: -1px; border-top: 2px solid var(--acc); border-right: 2px solid var(--acc); }
.corner.bl { bottom: -1px; left: -1px; border-bottom: 2px solid var(--acc); border-left: 2px solid var(--acc); }
.corner.br { bottom: -1px; right: -1px; border-bottom: 2px solid var(--acc); border-right: 2px solid var(--acc); }
/* No decorative title bar here: img/app-editor.webp carries the application's own one, and drawing
   a second set of traffic lights over it named a different file than the one in the picture. */
/* The hero screenshot. No `aspect-ratio` here on purpose: the picture is a whole application window,
   and a fixed ratio would either letterbox it or crop the panels off its edges. The frame takes the
   shape of the screenshot, and the `width`/`height` attributes on the <img> reserve the space so a
   re-shot capture cannot shift the page. */
.app-canvas { display: block; width: 100%; height: auto; }
.g-cap { font-family: var(--mono); font-size: var(--fs-t2); letter-spacing: var(--tr-label); }
.hero-badge { position: absolute; bottom: 18px; left: -18px; background: var(--surface-2); border: 1px solid var(--line); padding: 12px 15px; box-shadow: 0 18px 34px -18px rgba(23, 20, 15, .4); }
.hero-badge .mono { font-size: var(--fs-t1); }
.hero-badge .strong { font-size: var(--fs-t5); margin-top: 2px; }
.hero-formats { display: flex; flex-wrap: wrap; gap: 10px 26px; align-items: center; font-size: var(--fs-t2); color: var(--ink-soft); padding-bottom: 30px; }

/* ---- sections ---- */
.section { padding-top: 76px; padding-bottom: 12px; scroll-margin-top: 70px; }
.section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap; margin-bottom: 34px; }
.section-head.block { display: block; }
.section-head.center { text-align: center; display: block; }
.kicker { font-family: var(--mono); font-size: var(--fs-t2); letter-spacing: var(--tr-eyebrow); color: var(--acc-ink); }
h2 { font-weight: 700; font-size: var(--fs-section); line-height: var(--lh-head); margin-top: 12px; }
.section-sub { font-size: var(--fs-t6); line-height: var(--lh-read); color: var(--ink-soft); max-width: 400px; margin-top: 0; }
.section-sub.mw { max-width: 460px; margin-top: 18px; }
.section-sub.center-sub { margin: 12px auto 0; max-width: 480px; }
.mw-lg { max-width: 640px; }
.center { text-align: center; }
.mb-lg { margin-bottom: 40px; }

/* ---- cards ---- */
.card-grid { display: grid; gap: 16px; }
.cols-4 { grid-template-columns: repeat(4, 1fr); }
.cols-2 { grid-template-columns: repeat(2, 1fr); }
.card { position: relative; background: var(--surface); border: 1px solid var(--line); padding: 26px 22px 24px; display: flex; flex-direction: column; gap: 12px; }
.card.feature { min-height: 186px; gap: 0; padding: 24px 22px 26px; }
.card-no { font-size: var(--fs-t2); color: var(--acc-ink); }
.card-ico { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; }
.card-ico svg { width: 100%; height: 100%; }
.card-ico.acc { color: var(--acc-ink); margin-bottom: 16px; }
.card-ico.ink { color: var(--ink); width: 36px; height: 36px; }
/* Was 16.5px — half a pixel above the 16px paragraph in the same card, which is not a heading, it
   is a rounding error. d1 is the rung above the text ramp and the one a card title belongs on. */
.card h3 { font-weight: 600; font-size: var(--fs-d1); line-height: var(--lh-lede); margin-bottom: 7px; }
.card p { font-size: var(--fs-t3); line-height: var(--lh-read); color: var(--ink-soft); }
.card.feature h3 { font-size: var(--fs-d1); }
.badge-soon { position: absolute; top: 16px; right: 16px; font-family: var(--mono); font-size: var(--fs-t1); letter-spacing: var(--tr-eyebrow); color: var(--acc-ink); border: 1px solid var(--acc); border-radius: 4px; padding: 3px 6px; }

/* ---- why ---- */
.why-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 52px; align-items: center; }
.compare { width: 100%; border-collapse: collapse; border: 1px solid var(--line); margin-top: 26px; }
.compare td { padding: 14px 18px; border: 1px solid var(--line); vertical-align: top; width: 50%; }
.compare .mono { display: block; font-size: var(--fs-t1); }
.cmp-v { display: block; font-size: var(--fs-t4); margin-top: 5px; }

/* ---- gallery ---- */
.gallery { display: grid; grid-template-columns: 2fr 1fr 1fr; grid-auto-rows: 1fr; gap: 16px; }
/* A gallery tile is a fixed grid cell with a picture filling it — the image is positioned rather
   than flowed so a tall / wide cell keeps the row rhythm the grid set, and `cover` crops instead of
   letterboxing. `overflow: hidden` because the crop must not paint outside its tile. */
.g-item { position: relative; min-height: 200px; overflow: hidden; margin: 0; }
.g-item img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; }
.g-tall { grid-row: span 2; }
.g-wide { grid-column: span 2; }
.g-cap { position: absolute; left: 12px; bottom: 11px; color: #fff; background: rgba(20, 17, 12, .62); padding: 4px 8px; }

/* ---- workflow band ---- */
.band { background: var(--surface); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); margin-top: 76px; scroll-margin-top: 70px; }
.band .wrap { padding-top: 64px; padding-bottom: 64px; }
.steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; }
.step { position: relative; padding-right: 20px; }
.step-node { width: 11px; height: 11px; background: var(--acc); display: inline-block; vertical-align: middle; }
.step-line { display: inline-block; height: 1px; width: calc(100% - 21px); background: var(--line); vertical-align: middle; margin-left: 10px; }
.step-no { font-size: var(--fs-t2); color: var(--acc-ink); margin-top: 16px; }
.step h3 { font-weight: 600; font-size: var(--fs-d1); margin: 6px 0 7px; }
.step p { font-size: var(--fs-t3); line-height: var(--lh-read); color: var(--ink-soft); max-width: 180px; }

/* ---- pricing ---- */
.billing-toggle { display: flex; justify-content: center; align-items: center; gap: 4px; margin: 26px auto 34px; width: fit-content; background: var(--surface); border: 1px solid var(--line); border-radius: 999px; padding: 4px; }
.billing-toggle button { border: none; cursor: pointer; border-radius: 999px; padding: 8px 18px; font-size: var(--fs-t4); font-family: var(--geo); font-weight: 600; }
.billing-toggle .bt-on { background: var(--acc); color: var(--on-acc); }
.billing-toggle .bt-off { background: transparent; color: var(--ink-soft); }
.save-note { font-size: var(--fs-t1); color: var(--acc-ink); padding: 0 10px; }
.plans { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; align-items: start; }
.plan { position: relative; background: var(--surface); border: 1px solid var(--line); padding: 30px 26px 28px; display: flex; flex-direction: column; }
.plan h3 { font-weight: 600; font-size: var(--fs-d2); }
.plan-tag { font-size: var(--fs-t3); color: var(--ink-soft); margin-top: 6px; min-height: 40px; }
.plan-price { display: flex; align-items: baseline; gap: 4px; margin: 14px 0 2px; }
.amount { font-weight: 700; font-size: var(--fs-d5); letter-spacing: var(--tr-head); }
.per { font-size: var(--fs-t3); color: var(--ink-soft); }
.plan-billed { font-size: var(--fs-t1); color: var(--ink-soft); min-height: 16px; }
.plan hr { border: none; border-top: 1px solid var(--line); margin: 22px 0; }
.plan-features { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 11px; }
.plan-features li { position: relative; padding-left: 26px; font-size: var(--fs-t3); }
.plan-features li::before { content: ""; position: absolute; left: 0; top: 4px; width: 15px; height: 9px; border-left: 2.4px solid var(--acc); border-bottom: 2.4px solid var(--acc); transform: rotate(-45deg); }
.plan-popular { border-color: var(--acc); }
.plan-flag { position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--acc); }
.plan-pop { position: absolute; top: 16px; right: 18px; font-size: var(--fs-t1); letter-spacing: var(--tr-eyebrow); color: var(--acc-ink); }
.enterprise { margin-top: 16px; background: var(--surface); border: 1px solid var(--line); padding: 22px 26px; display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.enterprise p { font-size: var(--fs-t4); color: var(--ink-soft); }
.enterprise strong { color: var(--ink); font-size: var(--fs-t6); }

/* ---- references ---- */
.refs { text-align: center; }
.refs-head { font-size: var(--fs-t1); letter-spacing: var(--tr-eyebrow); color: var(--ink-soft); margin-bottom: 22px; }
.ref-row { display: flex; flex-wrap: wrap; gap: 20px 44px; justify-content: center; align-items: center; }
/* No `opacity: .62` here. `--ink-soft` is already the receding colour; multiplying it took the one
   countable, checkable strip on the page ("62 dolap preseti", "3 işletim sistemi") down to 2.53:1 —
   the faintest text on the site was the only text on it that is a verifiable fact. */
.ref-row span { font-weight: 700; font-size: var(--fs-d1); color: var(--ink-soft); }

/* ---- closing CTA ---- */
.cta-dark { position: relative; background: var(--dark-bg); color: #f1ece4; padding: 64px 48px; margin-top: 40px; overflow: hidden; text-align: center; }
.grid-bg-dark { background-image: linear-gradient(rgba(255, 255, 255, .045) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, .045) 1px, transparent 1px); background-size: 28px 28px; }
.cta-dark h2 { font-size: var(--fs-claim); max-width: 620px; margin: 0 auto; letter-spacing: var(--tr-head); }
.cta-dark p { font-size: var(--fs-d1); color: #b0a693; margin: 16px auto 0; max-width: 480px; }
.cta-dark .corner { width: 18px; height: 18px; }
.acc-corner.tl { border-top-color: #e39a3a; border-left-color: #e39a3a; top: 0; left: 0; }
.acc-corner.br { border-bottom-color: #e39a3a; border-right-color: #e39a3a; bottom: 0; right: 0; }

/* ---- footer ---- */
.site-footer { padding-top: 66px; padding-bottom: 30px; }
.footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr; gap: 32px; }
.footer-brand { max-width: 280px; }
.footer-desc { font-size: var(--fs-t3); line-height: var(--lh-read); color: var(--ink-soft); margin: 16px 0 14px; }
.footer-col { display: flex; flex-direction: column; gap: 10px; }
.footer-h { font-size: var(--fs-t1); letter-spacing: var(--tr-eyebrow); color: var(--ink-soft); margin-bottom: 4px; }
.footer-col a { font-size: var(--fs-t3); color: var(--ink); }
.footer-col a:hover { color: var(--acc-ink); }
.footer-bottom { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin-top: 44px; padding-top: 22px; border-top: 1px solid var(--line); flex-wrap: wrap; }
.footer-bottom .mono { font-size: var(--fs-t2); }
.footer-legal { display: flex; gap: 18px; font-size: var(--fs-t3); }
.footer-legal a { color: var(--ink-soft); }

/* ---- responsive ---- */
@media (max-width: 960px) {
  .cols-4 { grid-template-columns: repeat(2, 1fr); }
  .hero-inner, .why-grid { grid-template-columns: 1fr; }
  .steps { grid-template-columns: repeat(2, 1fr); gap: 24px; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 620px) {
  .wrap { padding-left: 20px; padding-right: 20px; }
  .header-inner { gap: 16px; }
  .cols-4, .cols-2, .plans, .gallery { grid-template-columns: 1fr; }
  .g-tall, .g-wide { grid-row: auto; grid-column: auto; }
  .steps { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .link-login { display: none; }
  /* header primary CTA is redundant on small screens (hero + closing CTAs remain) — hide it so the
     TR/EN toggle + theme button never crowd or overflow the header on phones. */
  .header-actions .btn-primary { display: none; }
  .cta-dark { padding: 44px 24px; }
}
/* ⚑ Last, and it has to be last. These blocks are plain `max-width` queries of equal specificity,
   so at 320px the 960, 620 and 430 rules all match and the file order decides. This block used to
   sit *above* the 620 one, which meant anything it set that 620 also set was silently overridden at
   exactly the widths it was written for. Keep the breakpoints in descending order. */
@media (max-width: 430px) {
  /* The theme control went from one 38px icon button to a three-way segment of ~104px, which is 66px
     more header than a 320px phone has. The wordmark is what gives: the mitre-M on its own is still
     unmistakably the brand, and nobody at 320px is reading "MobiCAM" off the top-left corner to know
     what site they are on. */
  .brand-word { display: none; }

  /* The footer's first column carries the contact address, and an e-mail address is one unbreakable
     run: `merhaba@mobicamsoft.com` measures 225px of Space Mono, both engines agreeing to the tenth
     of a pixel. A grid track's `min-width` is `auto`, so that 225px is a floor the column cannot go
     under — and two such columns plus a 32px gap need a 372px viewport. Below that, every page on
     the site scrolled sideways by 32px: `deploy/audit-layout.mjs` measures it, and a thumb finds it.
     One column below 430px, so the address has the full 280px to itself. Letting it break mid-string
     would also fit, but an e-mail wrapped across two lines is not one a reader can copy by eye. */
  .footer-grid { grid-template-columns: 1fr; gap: 26px; }
}

/* ============================================================================
   MOTION

   Brand read: a precision instrument, a drafting table. Nothing bounces, nothing
   overshoots, nothing loops. One easing curve throughout — ease-out, decisive
   arrival, no rebound.

   THE RULE THAT KEEPS THIS SAFE: every reveal moves on Y and opacity only. Never
   X, never rotate. `deploy/audit-layout.mjs` measures documentElement.scrollWidth
   against clientWidth at ten widths in two engines, and transforms count toward
   scrollWidth — a horizontal one would put the whole site into sideways scroll at
   some width nobody tested by hand. Scale is allowed only inside a clipped
   ancestor, which is why the gallery zoom is fine: .g-item already has
   overflow: hidden.
   ============================================================================ */

/* Content is VISIBLE by default. Only boot.js adding .js-reveal to <html> opts a
   page into hiding it, and boot.js only does that when IntersectionObserver
   exists and reduced-motion is off. JS off, a CSP refusal, an old browser →
   nothing is ever hidden and the page is simply static. The inverse — hide in
   CSS, show in JS — loses the whole page to one failed script. */
[data-reveal] {
  transition: opacity .55s cubic-bezier(.22, .61, .36, 1),
              transform .55s cubic-bezier(.22, .61, .36, 1);
}
.js-reveal [data-reveal] { opacity: 0; transform: translateY(14px); }
[data-reveal].is-in { opacity: 1; transform: none; }

/* Stagger is pure CSS: the observer marks the container, the children arrive in
   sequence. 60ms steps — brisk enough to read as one gesture rather than a queue.
   Capped at 8, which is the widest grid on the site (the eight feature cards). */
[data-reveal-stagger] > * {
  transition: opacity .5s cubic-bezier(.22, .61, .36, 1),
              transform .5s cubic-bezier(.22, .61, .36, 1);
}
.js-reveal [data-reveal-stagger] > * { opacity: 0; transform: translateY(12px); }
[data-reveal-stagger].is-in > * { opacity: 1; transform: none; }
[data-reveal-stagger].is-in > :nth-child(2) { transition-delay: 60ms; }
[data-reveal-stagger].is-in > :nth-child(3) { transition-delay: 120ms; }
[data-reveal-stagger].is-in > :nth-child(4) { transition-delay: 180ms; }
[data-reveal-stagger].is-in > :nth-child(5) { transition-delay: 240ms; }
[data-reveal-stagger].is-in > :nth-child(6) { transition-delay: 300ms; }
[data-reveal-stagger].is-in > :nth-child(7) { transition-delay: 360ms; }
[data-reveal-stagger].is-in > :nth-child(8) { transition-delay: 420ms; }

/* Hover lift. The (hover: hover) guard is not optional: without it a tap on a
   phone leaves the card stuck in its lifted state until you tap elsewhere. */
.card, .plan {
  transition: transform .18s cubic-bezier(.22, .61, .36, 1),
              border-color .18s ease, box-shadow .18s ease;
}
@media (hover: hover) and (pointer: fine) {
  .card:hover, .plan:hover {
    transform: translateY(-3px);
    border-color: var(--line-strong);
    box-shadow: 0 14px 28px -18px rgba(23, 20, 15, .35);
  }
}

/* The header gains an edge once the page has moved under it — and nothing else.
   Deliberately no height shrink: .section carries scroll-margin-top: 70px, so a
   header that changes height makes every in-page anchor land wrong by the
   difference. A precision brand does not have a header that moves. */
.site-header { transition: box-shadow .2s ease, background .2s ease; }
[data-scrolled] .site-header {
  box-shadow: 0 1px 0 var(--line), 0 10px 24px -22px rgba(0, 0, 0, .5);
}

/* Gallery. Safe by construction — .g-item is overflow: hidden, which is exactly
   the clipped-ancestor case the overflow probe skips. */
.g-item img { transition: transform .5s cubic-bezier(.22, .61, .36, 1); }
@media (hover: hover) and (pointer: fine) {
  .g-item:hover img { transform: scale(1.04); }
}
.g-cap { transition: background .2s ease; }

/* The hero is above the fold by definition, so it needs no observer — it just
   arrives. `both` so the start state applies during the delay rather than
   flashing at full opacity first. The four amber crop-marks draw last: a
   drafting gesture, and the site's own idiom. */
@keyframes mc-rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes mc-fade { from { opacity: 0; } to { opacity: 1; } }

.js-reveal .hero-copy > * { animation: mc-rise .6s cubic-bezier(.22, .61, .36, 1) both; }
.js-reveal .hero-copy > :nth-child(2) { animation-delay: .07s; }
.js-reveal .hero-copy > :nth-child(3) { animation-delay: .14s; }
.js-reveal .hero-copy > :nth-child(4) { animation-delay: .21s; }
.js-reveal .hero-copy > :nth-child(5) { animation-delay: .28s; }
.js-reveal .app-frame { animation: mc-rise .7s cubic-bezier(.22, .61, .36, 1) .12s both; }
.js-reveal .app-frame .corner { animation: mc-fade .35s ease .55s both; }
.js-reveal .hero-badge { animation: mc-rise .5s cubic-bezier(.22, .61, .36, 1) .7s both; }
.js-reveal .hero-formats { animation: mc-fade .5s ease .5s both; }

/* No .grid-bg animation and no parallax anywhere. A 28px grid translating at
   60fps is jank on a mid-range Android, and nothing in the harness measures
   jank — it would ship unnoticed. */

/* Belt to the per-feature braces. boot.js already refuses to add .js-reveal
   under reduced-motion, so nothing is ever hidden either; this catches the
   hovers, the header and anything added later that forgets to ask. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================================
   NAVIGATION

   There was none below 960px: `.nav { display: none }` and nothing in its place.
   On five pages that was survivable. It is not on a site with a page per module.

   One copy of the markup, laid out two ways. Above 960px the panel is simply the
   header bar. Below it, `.nav-check:checked` turns it into a full-height sheet.
   Everything is moved by CSS; no element exists twice, so no id is duplicated and
   no control has two states to keep in step.

   This was a <details> first, and that was wrong in a way worth recording: the
   content of a CLOSED <details> is not hit-tested even when CSS gives it
   `display: flex`. Above 960px, where the panel is supposed to be the ordinary
   header bar, `elementFromPoint` over the theme buttons returned the wrapper div
   and clicking them did nothing — the language and theme controls were dead on
   every desktop, in both engines, while every computed style said "visible". A
   checkbox has no rendering-subtree behaviour to trip over.
   ============================================================================ */

/* Visually hidden but still focusable and still checkable: Tab reaches it, Space
   opens the menu. Its accessible name comes from the <label>. */
.nav-check { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

@media (min-width: 961px) {
  .nav-toggle { display: none; }
  .nav-drawer, .nav-panel { display: flex; flex: 1; align-items: center; gap: 30px; }
  .nav-controls { margin-left: auto; display: flex; align-items: center; gap: 14px; }
}

@media (max-width: 960px) {
  .nav-drawer { margin-left: auto; }
  .nav-toggle {
    width: 40px; height: 40px; padding: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 9px; cursor: pointer;
  }
  /* The input is off-screen, so the focus ring has to be drawn on the label instead —
     otherwise a keyboard user tabbing to the menu sees nothing at all. */
  .nav-check:focus-visible + .nav-drawer .nav-toggle {
    outline: 2px solid var(--acc); outline-offset: 2px;
  }

  .burger i {
    display: block; width: 18px; height: 1.6px; background: var(--ink); margin: 3px 0;
    transition: transform .2s cubic-bezier(.22, .61, .36, 1), opacity .15s ease;
  }
  .nav-check:checked + .nav-drawer .burger i:nth-child(1) { transform: translateY(4.6px) rotate(45deg); }
  .nav-check:checked + .nav-drawer .burger i:nth-child(2) { opacity: 0; }
  .nav-check:checked + .nav-drawer .burger i:nth-child(3) { transform: translateY(-4.6px) rotate(-45deg); }

  /* The sheet starts below the header bar rather than over it, so the burger stays visible and
     tappable while the panel is open — the way back out is never hidden.

     `position: fixed` here is NOT relative to the viewport. `.site-header` carries
     `backdrop-filter: blur(12px)`, and a backdrop-filter makes an element a containing block for
     fixed-position descendants — so this box is positioned against the header, not the screen.
     Measured: the panel came out 67px tall instead of 717px.

     That is turned into an advantage rather than fought. `top: 100%` is exactly the header's bottom
     edge whatever the header's height, and `calc(100dvh - 100%)` is the rest of the screen, because
     a percentage height resolves against that same containing block. No magic number to go stale
     when the header's padding changes. `100vh` first for browsers without dvh; on the ones that
     have it, dvh is what keeps the sheet right while a phone's toolbar collapses. */
  .nav-panel { display: none; }
  .nav-check:checked + .nav-drawer .nav-panel {
    position: fixed; top: 100%; left: 0; right: 0; bottom: auto; z-index: 79;
    height: calc(100vh - 100%);
    height: calc(100dvh - 100%);
    background: var(--bg); border-top: 1px solid var(--line);
    padding: 22px 20px 44px; overflow-y: auto; overscroll-behavior: contain;
    display: flex; flex-direction: column; gap: 24px;
  }
  /* A full-height sheet is the largest piece of typography this site ever gets, and it used to
     spend it one step above body copy: six links at 17px, each on a hairline, all crowded into the
     top 60% with the rest of the screen empty underneath. At 30px the links *are* the sheet, which
     is what a full-height sheet is for; the size is also the tap target, since a 17px label inside
     a 48px row leaves the confident third of the row in the middle. `padding-left: 0` puts them on
     the panel's own 20px edge, so the list, the wordmark and the burger share one optical margin
     instead of being 2px apart. */
  .nav-panel .nav { flex-direction: column; gap: 0; margin: 0; }
  .nav-panel .nav a {
    font-size: var(--fs-d4); font-weight: 500; line-height: var(--lh-sub);
    padding: 18px 0; color: var(--ink);
  }
  .nav-panel .nav a[aria-current="page"] { color: var(--acc-ink); }
  /* The hairline under every link was what made the sheet read as a settings screen. At 30px with
     18px of padding the separation is already there; one line above the controls is enough, and
     `margin-top: auto` moves the sheet's empty 40% out from under everything and puts it between
     the links and the controls — which drops the call to action into the thumb's reach. */
  .nav-controls {
    display: flex; flex-wrap: wrap; align-items: center; gap: 14px;
    margin-top: auto; padding-top: 22px; border-top: 1px solid var(--line);
  }
  /* Inside the sheet there is room for the call to action and the sign-in link again. The 620px
     rules that hide both were written when these sat in the header bar and crowded it; a
     full-height sheet has no such problem, and hiding the way in to the portal on phones was only
     ever a symptom of that. */
  .nav-panel .btn-primary { display: inline-flex; }
  .nav-panel .link-login { display: inline; font-size: var(--fs-t6); }
  /* Four controls of four different widths cannot share a row, and `flex-wrap` was resolving that
     by dropping the button alone onto the last line — an accident that looked like a decision.
     Make it the decision: the pills and the sign-in link on one row, the button full width under
     them, at the 52px a primary action on a phone deserves. */
  .nav-panel .nav-controls .btn-primary {
    flex: 0 0 100%; justify-content: center; min-height: 52px; font-size: var(--fs-t6);
  }
}

/* The page must not scroll under an open sheet. A class, never an inline style: the CSP forbids
   the latter. Only site.js sets it, and only while the sheet is genuinely a sheet. */
html.nav-open, html.nav-open body { overflow: hidden; }

/* The current page, marked in the desktop bar too. */
.nav a[aria-current="page"] { color: var(--ink); }

/* ============================================================================
   PAGE ARCHETYPES

   Three shapes cover the whole site, so a new page is composition rather than
   design: a MODULE page (masthead → alternating picture/prose rows → a capability
   grid → a spec table → the closing CTA), a UTILITY page (masthead → prose column,
   which borrows kilavuz.css), and the HOME page.
   ============================================================================ */

/* ---- masthead: the top of every page that is not the home page ---- */
.masthead { padding: 58px 0 44px; border-bottom: 1px solid var(--line); }
.masthead h1 {
  font-size: var(--fs-title); line-height: var(--lh-display); letter-spacing: var(--tr-display);
  margin: 14px 0 0; max-width: 17ch;
}
.masthead .lede { margin-top: 18px; max-width: 62ch; }
.masthead .hero-cta { margin-top: 26px; }
.masthead-sub { margin-top: 20px; display: flex; flex-wrap: wrap; gap: 8px 22px; font-size: var(--fs-t3); }

/* ---- alternating picture / prose rows ---- */
.mod-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: 46px; align-items: center;
  padding: 56px 0; border-bottom: 1px solid var(--line);
}
/* The picture leads on even rows. `direction` rather than `order` so the reading order in the
   markup stays the reading order for a screen reader and for a page with no CSS at all. */
.mod-row.flip > :first-child { order: 2; }
/* Every argument on this site is written inside a `.mod-row`; every inventory and every table sits
   under a plain `.section-head`. The two heading scales were 31 and 38 — so the page's case was set
   seven pixels smaller than its table stakes, and the typography argued the opposite of the
   editing. `.lead` is the exception, used once per page, for the row that carries the page's claim;
   `:has()` takes the other half without touching any markup — a heading whose job is to introduce a
   spec table is a label. Browsers without `:has()` keep the section rank, which is what they showed
   before, so nothing regresses.

   The four ranks a module page uses are now four consecutive windows on one ramp, so /cnc-uretim
   reads 53 · 44 · 37 · 31 · 26 down the page — title, claim, inventory, argument, table label — at
   every width, instead of the 50 · 44 · 38 · 31 · 26 that held on a desktop and collapsed to
   30 · 30 · 30 · 22 · 26 on a phone. That collapse also INVERTED the last two: a spec table's label
   outranked the argument beside it on every screen under 846 px. */
.mod-row h2 { font-size: var(--fs-argument); line-height: var(--lh-sub); letter-spacing: var(--tr-sub); }
.mod-row.lead h2 { font-size: var(--fs-claim); line-height: var(--lh-head); letter-spacing: var(--tr-head); }
.section-head:has(+ .spec-wrap) h2 { font-size: var(--fs-label); line-height: var(--lh-sub); letter-spacing: var(--tr-sub); }
.mod-row .kicker { margin-bottom: 10px; }
.mod-row p { color: var(--ink-soft); font-size: var(--fs-t5); line-height: var(--lh-read); margin-top: 14px; }
.mod-row ul { margin: 16px 0 0; padding-left: 0; list-style: none; display: grid; gap: 9px; }
.mod-row li { position: relative; padding-left: 24px; font-size: var(--fs-t4); color: var(--ink-soft); }
.mod-row li::before {
  content: ""; position: absolute; left: 2px; top: 7px; width: 9px; height: 5px;
  border-left: 2px solid var(--acc); border-bottom: 2px solid var(--acc); transform: rotate(-45deg);
}
.mod-shot { position: relative; margin: 0; }
.mod-shot img { width: 100%; height: auto; border: 1px solid var(--line); background: var(--surface); }
.mod-shot figcaption { margin-top: 10px; font-size: var(--fs-t2); color: var(--ink-soft); font-family: var(--mono); }

/* A picture we do not have yet says so, rather than shipping an empty frame or a stock photo. */
.mod-shot.pending {
  border: 1px dashed var(--line-strong); background: var(--surface);
  min-height: 220px; display: flex; align-items: center; justify-content: center;
  padding: 28px; text-align: center;
}
.mod-shot.pending p { font-family: var(--mono); font-size: var(--fs-t2); color: var(--ink-soft); margin: 0; }

/* ---- the typed prompt, set at reading size, and the object the model may answer with ----
   The AI page's own evidence. There is no screenshot of that panel yet and this is not pretending
   to be one: it is the sentence and the nine fields, as type. Nothing here needs JavaScript and
   nothing needs a font the site does not already serve, which is why it could be built while the
   four captures the rest of the page wants still cannot.

   It takes the ARGUMENT rank rather than the claim rank it is rhetorically owed, and that is a
   property of the face rather than a demotion. Space Mono's advance is 0.6em against Jost's ~0.5em,
   so a rung of mono occupies a fifth more line and reads about a rung larger — at the claim rank
   this sentence would out-weigh the page's own h1 beside it.

   It also buys the line. A prompt broken across "üç / çekmeceli" reads as two prompts, and measured
   in WebKit the argument rank holds all 34 characters on ONE line down to 620px and gives up two
   lines at 470; the claim rank breaks by 700px and is on three lines at 390 where this is on two.
   150px more of viewport with the sentence intact, for one rung. */
.prompt-demo { margin-top: 30px; border: 1px solid var(--line); background: var(--surface); }
.prompt-tag { font-size: var(--fs-t1); letter-spacing: var(--tr-label); color: var(--acc-ink); }
.prompt-said { padding: 26px 30px 30px; border-bottom: 1px solid var(--line); }
.prompt-line {
  margin-top: 16px; font-family: var(--mono); font-size: var(--fs-argument);
  line-height: var(--lh-lede); letter-spacing: var(--tr-sub); color: var(--ink); text-wrap: balance;
}
.prompt-got { padding: 26px 30px 30px; }
/* Column-major, and that is the whole reason for the explicit row count: a plain two-column grid
   fills across, which puts field 2 to the RIGHT of field 1 and makes the nine read
   label · width · depth · shelves · leg down one side. They are in `AiCabinet`'s declaration order
   and reading them in it is the point, so the first five go down the left and the last four down
   the right. `repeat(5, …)` is therefore ceil(9/2) and moves when a field is added to the struct. */
.prompt-fields {
  margin: 18px 0 0; display: grid; gap: 0 40px;
  grid-template-columns: 1fr 1fr; grid-template-rows: repeat(5, auto); grid-auto-flow: column;
}
.pf {
  display: grid; grid-template-columns: 124px 1fr; align-items: baseline; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--line);
}
.pf dt { font-family: var(--mono); font-size: var(--fs-t2); color: var(--ink-soft); }
.pf dd { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; font-size: var(--fs-t4); color: var(--ink); }
/* The provenance is prose, not code — set in the text face so it cannot be misread as a value. */
.pf-src { font-family: var(--geo); font-size: var(--fs-t2); color: var(--ink-soft); }
/* Amber marks the fields the sentence actually stated; the rest came from the standards table and
   stay quiet. The distinction is the whole argument of the block. */
.pf.src-text .pf-src { color: var(--acc-ink); }
.prompt-foot { margin-top: 20px; font-size: var(--fs-t4); line-height: var(--lh-read); color: var(--ink-soft); max-width: 76ch; }
.prompt-foot em { color: var(--ink); font-style: normal; font-weight: 600; }

/* ---- a plain spec table, narrower than the manual's ---- */
.spec { width: 100%; border-collapse: collapse; margin-top: 26px; font-size: var(--fs-t4); }
.spec th, .spec td { text-align: left; padding: 12px 14px; border-bottom: 1px solid var(--line); vertical-align: top; }
.spec th { font-family: var(--mono); font-size: var(--fs-t1); letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--ink-soft); font-weight: 400; }
.spec td:first-child { font-weight: 600; width: 34%; }
.spec-wrap { overflow-x: auto; }

/* ---- a band of numbered stages, for the production chain ---- */
.chain { display: grid; grid-template-columns: repeat(6, 1fr); gap: 18px; margin-top: 34px; }
.chain-step { border-top: 2px solid var(--acc); padding-top: 14px; }
.chain-step .mono { font-size: var(--fs-t1); color: var(--acc-ink); }
.chain-step h3 { font-size: var(--fs-t5); margin: 6px 0 6px; }
.chain-step p { font-size: var(--fs-t2); color: var(--ink-soft); line-height: var(--lh-read); }

/* ---- a short list of related pages at the foot of a module ---- */
.next-up { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 30px; }
.next-up a {
  display: block; border: 1px solid var(--line); background: var(--surface); padding: 18px 20px;
  color: var(--ink); transition: transform .18s cubic-bezier(.22,.61,.36,1), border-color .18s ease;
}
.next-up a .mono { font-size: var(--fs-t1); color: var(--acc-ink); display: block; margin-bottom: 6px; }
.next-up a span:not(.mono) { font-weight: 600; font-size: var(--fs-t5); }
@media (hover: hover) and (pointer: fine) {
  .next-up a:hover { transform: translateY(-3px); border-color: var(--line-strong); }
}

/* A full-width notice that must not be missed — the pricing page's pilot banner. */
.notice {
  border: 1px solid var(--acc); background: color-mix(in srgb, var(--acc) 10%, transparent);
  padding: 18px 22px; margin: 26px 0 0; display: flex; gap: 14px; align-items: flex-start;
}
.notice .mono { font-size: var(--fs-t1); color: var(--acc-ink); letter-spacing: var(--tr-label); white-space: nowrap; padding-top: 2px; }
.notice p { font-size: var(--fs-t4); line-height: var(--lh-read); }

@media (max-width: 960px) {
  .chain { grid-template-columns: repeat(3, 1fr); }
  .next-up { grid-template-columns: 1fr; }
}
/* One column of fields before the label column would have to shrink: `leg_height_mm` is 13
   characters and is what sets that 124px. */
@media (max-width: 860px) {
  .prompt-fields { grid-template-columns: 1fr; grid-template-rows: none; grid-auto-flow: row; gap: 0; }
}
@media (max-width: 620px) {
  .mod-row { grid-template-columns: 1fr; gap: 26px; padding: 40px 0; }
  .mod-row.flip > :first-child { order: 0; }
  .chain { grid-template-columns: 1fr 1fr; }
  .masthead { padding: 38px 0 32px; }
  .notice { flex-direction: column; gap: 8px; }
  .prompt-said, .prompt-got { padding-left: 20px; padding-right: 20px; }
  /* Below this the two-column row stops paying: the value wraps under its own name anyway, and a
     124px gutter next to a 40-character viewport is most of the line. */
  .pf { grid-template-columns: 1fr; gap: 2px; padding: 11px 0; }
}
