/* Graphite: one dark look for manufacturers. Every colour is a token here; there is no light variant by design.
   One accent (blue) for actions and emphasis; danger only for failures and form errors. */
:root {
  color-scheme: dark;
  --bg: #05070A;
  --bg-glass: rgb(5 7 10 / 0.92);
  --panel: #0B0F14;
  --line: #161A20;
  --line-strong: #1E242C;
  --fg: #F5F7FA;
  --fg-2: #C9D1D9;
  --muted: #9AA4AF;
  --dim: #737D89;
  --accent: #1D6FD8;
  --accent-hover: #1A63C4;
  --accent-hi: #6CB4FF;
  --on-accent: #FFFFFF;
  --danger: #FF6B6B;
  --draw: #DCE3EA;
  /* File badges of "send and get" (format_badges.py): a quiet fill per family under one dark ink, each at least 4.5:1,
     and a lighter fold; plain words, links, code and made parts are a grey outline. CAD takes the accent. */
  --badge-ink: var(--bg);
  --badge-cad: var(--accent-hi);
  --badge-cad-fold: #B6DAFF;
  --badge-drawing: #E2A27F;
  --badge-drawing-fold: #F0D0BF;
  --badge-sheet: #87C6A0;
  --badge-sheet-fold: #C3E2CF;
  --badge-image: #AEB7C1;
  --badge-image-fold: #D6DBE0;
  --badge-text-ink: var(--fg-2);
  --badge-text-edge: var(--muted);
  --font-head: "Inter Tight", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, Menlo, monospace;
  --wrap: 1200px;
  --gutter: 24px;
  --radius: 8px;
  --radius-lg: 12px;
  --sec: 112px;
}
@media (max-width: 699px) {
  :root { --gutter: 16px; --sec: 64px; }
}
/* Graphite base: page, type, header, footer and the parts every page uses. */
*, *::before, *::after { box-sizing: border-box; }
/* Hero figures and tab panels set display, which would otherwise beat the hidden attribute. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: 88px; }
body { margin: 0; background: var(--bg); color: var(--fg); font: 400 16px/1.6 var(--font-body); -webkit-font-smoothing: antialiased; }
img, svg { max-width: 100%; }
img { display: block; height: auto; }
a { color: inherit; }
a:hover { color: var(--accent-hi); }
:focus-visible { outline: 2px solid var(--accent-hi); outline-offset: 3px; border-radius: 4px; }
h1, h2, h3 { margin: 0; font-family: var(--font-head); font-weight: 800; line-height: 1.1; letter-spacing: -0.01em; text-wrap: balance; }
h1 { font-size: clamp(36px, 5vw, 56px); font-weight: 600; }
h2 { font-size: clamp(28px, 3.4vw, 36px); }
h3 { font-size: 20px; font-weight: 600; line-height: 1.25; }
p { margin: 0; }
b, strong { font-weight: 500; }
mark { background: none; color: inherit; }
.hl, mark.hl { color: var(--accent-hi); font-weight: 500; font-style: normal; }
.wrap { max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }
.narrow { max-width: 880px; }
.sec { padding-block: var(--sec); border-top: 1px solid var(--line); }
.sec:first-child { border-top: 0; }
.sec-head { display: grid; gap: 14px; max-width: 760px; margin: 0 auto 48px; text-align: center; justify-items: center; }
.lede { max-width: 65ch; font-size: 18px; line-height: 1.6; color: var(--fg-2); }
.fine { font-size: 14px; color: var(--muted); }
.mono { font-family: var(--font-mono); }
.eyebrow { font: 500 12px/1.2 var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip { position: absolute; top: -48px; left: 16px; z-index: 20; padding: 8px 12px; border-radius: var(--radius); background: var(--fg); color: var(--bg); }
.skip:focus { top: 12px; }

/* Header */
.top { position: sticky; top: env(safe-area-inset-top, 0px); z-index: 10; background: var(--bg-glass); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); border-bottom: 1px solid var(--line); }
.top-row { display: flex; align-items: center; gap: 24px; min-height: 64px; }
.brand { font: 600 20px/1 var(--font-head); letter-spacing: -0.01em; text-decoration: none; color: var(--fg); }
.nav { display: flex; gap: 28px; margin-inline: auto; }
.nav a { font-size: 15px; white-space: nowrap; text-decoration: none; color: var(--fg-2); }
/* The current page is underlined too, so it is not told by colour alone. */
.nav a[aria-current="page"] { color: var(--fg); text-decoration-line: underline; text-decoration-thickness: 2px; text-decoration-color: var(--accent); text-underline-offset: 6px; }
/* On one line the header needs about 822px with Inter loaded, so below 900px the links wrap under the brand and the
   button. Wrapped only below 700px, it pushed the button past the page's edge up to about 800px. */
@media (max-width: 899px) {
  html { scroll-padding-top: 104px; } /* the wrapped header is 95px tall */
  .top-row { flex-wrap: wrap; row-gap: 0; padding-block: 10px; }
  .top-cta { margin-left: auto; }
  .nav { order: 3; width: 100%; margin: 0; gap: 20px; overflow-x: auto; padding-block: 8px 2px; }
}

/* Buttons and links */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 18px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: transparent; color: var(--fg); font: 500 16px/1 var(--font-body); text-decoration: none; cursor: pointer; }
.btn:hover { border-color: var(--muted); color: var(--fg); }
.btn.primary { border-color: var(--accent); background: var(--accent); color: var(--on-accent); }
.btn.primary:hover { border-color: var(--accent-hover); background: var(--accent-hover); color: var(--on-accent); }
.top .btn { min-height: 40px; padding: 0 14px; font-size: 15px; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; }
.more a { font-weight: 500; text-decoration: none; color: var(--fg-2); }
.more { margin-top: 32px; }

/* Shared parts */
.panel { background: var(--panel); border: 1px solid var(--line-strong); border-radius: var(--radius-lg); }
.checks { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
.checks li { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 10px; color: var(--fg-2); }
.checks li::before { content: "✓"; font-weight: 500; color: var(--accent-hi); }
.tablist { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-bottom: 28px; }
html:not(.js) .tablist { display: none; }
.tab { padding: 10px 16px; border: 1px solid var(--line-strong); border-radius: 999px; background: transparent; color: var(--muted); font: 500 14px/1 var(--font-body); cursor: pointer; }
.tab:hover { color: var(--fg); }
.tab[aria-selected="true"], .tab[aria-pressed="true"] { border-color: var(--accent); color: var(--fg); }
.table-wrap { overflow-x: auto; border: 1px solid var(--line-strong); border-radius: var(--radius-lg); }
.table { width: 100%; border-collapse: collapse; font-size: 15px; }
.table th, .table td { padding: 14px 16px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.table thead th { font: 500 12px/1.3 var(--font-mono); letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
.table tbody tr:last-child td { border-bottom: 0; }
.case-img { filter: grayscale(1) contrast(1.05); }

/* Footer */
.foot { padding-block: 48px calc(40px + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--line); }
.foot-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 24px 48px; }
.foot-brand { display: grid; gap: 8px; max-width: 420px; }
.foot-brand p { font-size: 14px; color: var(--muted); }
.foot-nav { display: flex; flex-wrap: wrap; gap: 12px 24px; margin-left: auto; }
.foot-nav a { font-size: 14px; text-decoration: none; color: var(--fg-2); }
.foot-note { margin-top: 32px; font-size: 13px; color: var(--dim); }
@media (max-width: 699px) { .foot-nav { margin-left: 0; } }
/* These links set their own colour after a:hover above, so they need their own hover. */
.nav a:hover, .foot-nav a:hover, .more a:hover { color: var(--fg); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; transition-delay: 0s !important; }
}
/* Graphite hero: a short head row (titles left; lede and buttons right), then one example's flow: what the client
   sends on the left, what we deliver on the right. The markup is the resting state, so it reads without script or
   motion; hero.js replays the flow by setting classes on .flow (playing, typing, attached, waiting) and showing one
   scene at a time. Motion lives only under those classes, and only when the reader allows motion. */
.hero { padding-block: 40px var(--sec); border-top: 0; }
.hero-head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px 56px; align-items: end; margin-bottom: 28px; }
.hero-titles { display: grid; gap: 14px; }
.hero h1 { font-size: clamp(34px, 3.9vw, 48px); }
.hero-side { display: grid; gap: 20px; }
.hero-side .lede { color: var(--fg); }
.kicker { font: 500 13px/1.4 var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent-hi); }
.hero-actions { display: flex; flex-wrap: wrap; gap: 16px 28px; }
.cta-item { display: grid; justify-items: start; gap: 8px; }
@media (max-width: 899px) { .hero-head { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 699px) { .hero { padding-top: 32px; } }

/* The flow: a bar with the example's name and the pause button, then the two panels with an arrow between. */
.flow { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }
.flow-bar { display: flex; align-items: center; gap: 12px; padding: 6px 8px 6px 14px; border: 1px solid var(--line-strong); border-radius: var(--radius); font-size: 13px; }
.flow-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; color: var(--fg); }
.flow-btn { display: grid; flex: none; place-items: center; width: 28px; height: 28px; padding: 0; border: 1px solid var(--line-strong); border-radius: 6px; background: transparent; color: var(--fg-2); cursor: pointer; }
.flow-btn svg { width: 12px; height: 12px; fill: currentColor; }
.flow-btn[aria-pressed="true"] .i-pause, .flow-btn[aria-pressed="false"] .i-play { display: none; }
/* Without script nothing replays, so the controls would do nothing. */
html:not(.js) .flow-btn, html:not(.js) .flow-steps { display: none; }
/* Under reduced motion the button never starts a play (hero.js); the steps still show each scene. */
@media (prefers-reduced-motion: reduce) { .flow-btn { display: none; } }
.flow-panels { display: grid; grid-template-columns: minmax(0, 5fr) auto minmax(0, 7fr); gap: 12px; align-items: stretch; }
.flow-arrow { align-self: center; font-size: 24px; line-height: 1; color: var(--accent-hi); }
.flow-side { display: grid; grid-template-rows: auto 1fr; gap: 12px; min-width: 0; padding: 14px; }
.flow-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; min-height: 28px; }
/* A fixed stage height keeps the page still while the scenes change; on phones the stage follows its scene. */
.flow-stage { position: relative; height: 420px; min-width: 0; border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--bg); }
@media (max-width: 1099px) {
  .flow-panels { grid-template-columns: minmax(0, 1fr); }
  .flow-arrow { justify-self: center; transform: rotate(90deg); }
}
@media (max-width: 699px) { .flow-stage { height: auto; } }

/* "You send": a request being written, its sketch attached, then sent. */
.msg { display: flex; flex-direction: column; gap: 14px; padding: 14px 16px; }
.msg-head { padding-bottom: 10px; border-bottom: 1px solid var(--line); font: 500 12px/1.2 var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.msg-text { font-size: 15px; line-height: 1.55; color: var(--fg); }
.msg-text .rest { color: transparent; }
.msg-file { display: grid; justify-items: start; gap: 6px; margin: 0; }
.msg-file img { width: min(100%, 240px); aspect-ratio: 3 / 2; object-fit: contain; border: 1px solid var(--line-strong); border-radius: 6px; }
.msg-file figcaption, .deliver figcaption { font: 12px/1.3 var(--font-mono); color: var(--muted); }
.deliver figcaption { text-align: center; }
.msg-foot { display: flex; justify-content: flex-end; margin-top: auto; }
.msg-go, .msg-done { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 14px; border-radius: 6px; font: 500 14px/1 var(--font-body); }
.msg-go { display: none; background: var(--accent); color: var(--on-accent); }
.msg-done { border: 1px solid var(--line-strong); color: var(--accent-hi); }
.msg-done svg, .approved svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.8; }
.flow.typing .msg-file { visibility: hidden; }
.flow.typing.attached .msg-file { visibility: visible; }
.flow.typing .msg-go { display: inline-flex; }
.flow.typing .msg-done { display: none; }

/* "We deliver": the steps beside its name, one scene at a time below. */
.flow-steps { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.flow-steps button { padding: 5px 10px; border: 1px solid var(--line-strong); border-radius: 999px; background: transparent; color: var(--muted); font: 500 12px/1.2 var(--font-mono); cursor: pointer; }
.flow-steps button:hover { color: var(--fg); }
.flow-steps button[aria-pressed="true"] { border-color: var(--accent); color: var(--fg); }
.scene { display: flex; flex-direction: column; gap: 14px; height: 100%; padding: 16px; }
.scene-title { font-weight: 500; color: var(--fg); }
.scene-fig { flex: 1; min-height: 0; margin: 0; }
.scene-fig img, .scene-fig .iso { width: 100%; height: 100%; object-fit: contain; }
.ctx { flex-direction: column; align-items: flex-start; }
.ctx li { font-size: 14px; }
.approved { display: inline-flex; align-items: center; align-self: flex-start; gap: 6px; padding: 4px 10px; border: 1px solid var(--accent); border-radius: 999px; font: 500 12px/1.2 var(--font-mono); color: var(--accent-hi); }
.plan { display: grid; gap: 10px; }
.plan-block { display: grid; gap: 6px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius); }
.plan-label { font: 500 11px/1.3 var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--dim); }
.plan ul { display: grid; gap: 2px; margin: 0; padding-left: 18px; }
.plan li, .plan-block > p + p { font-size: 14px; line-height: 1.45; color: var(--fg-2); }
.deliver { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 10px; flex: 1; min-height: 0; }
.deliver figure { display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: 6px; min-height: 0; margin: 0; }
.deliver img, .deliver video, .deliver .iso { width: 100%; height: 100%; min-height: 0; object-fit: contain; }
/* With a video, it plays in the larger column beside the render and the drawing, which stack; a lone drawing takes
   the whole first column. */
.deliver.has-video { grid-auto-flow: row; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); grid-template-rows: repeat(2, minmax(0, 1fr)); }
.deliver-video { grid-column: 2; grid-row: 1 / -1; }
.deliver.has-video figure:first-child:nth-last-child(2) { grid-row: 1 / -1; }
/* A bare drawing frames its geometry alone; its numbers would fall outside the frame, so they stay hidden. */
.flow .iso-dim, .flow .iso-label { display: none; }
@media (max-width: 699px) {
  .scene { height: auto; }
  .scene-fig img, .scene-fig .iso { height: auto; }
  .deliver { grid-auto-flow: row; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }
  .deliver img, .deliver video, .deliver .iso { height: auto; aspect-ratio: 3 / 2; }
  .deliver.has-video { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: none; }
  .deliver-video, .deliver.has-video figure:first-child:nth-last-child(2) { grid-column: 1 / -1; grid-row: auto; }
  .deliver video, .deliver.has-video figure:first-child:nth-last-child(2) img { aspect-ratio: 16 / 9; }
}
/* While "We deliver" waits for the request: three quiet dots. */
.flow.waiting .scenes::after { content: ""; position: absolute; top: 50%; left: 50%; width: 6px; height: 6px; margin: -3px 0 0 -15px; border-radius: 50%; background: var(--dim); box-shadow: 12px 0 var(--dim), 24px 0 var(--dim); }
@media (max-width: 699px) { .flow.waiting .scenes { min-height: 160px; } }

/* Motion: only while a play runs, and only when the reader allows it. */
@media (prefers-reduced-motion: no-preference) {
  .flow.typing [data-typed]::after { content: ""; display: inline-block; width: 2px; height: 1.1em; margin: 0 1px -0.2em; background: var(--accent-hi); animation: flow-blink 1s steps(1) infinite; }
  .flow.typing.attached .msg-file { animation: flow-attach 0.5s ease both; }
  .flow.playing:not(.typing) .msg-done { animation: flow-in 0.35s ease both; }
  .flow.waiting .scenes::after { animation: flow-wait 1.2s ease-in-out infinite; }
  .flow.playing .scene > * { animation: flow-in 0.4s ease both; }
  .flow.playing .ctx li, .flow.playing .plan-block { animation: flow-in 0.4s ease both calc(0.4s + var(--k) * 0.6s); }
  .flow.playing .approved { animation: flow-in 0.4s ease both 1.8s; }
  .flow.playing .deliver figure { animation: flow-in 0.4s ease both 0.2s; }
  .flow.playing .deliver figure:nth-child(2) { animation-delay: 0.5s; }
  .flow.playing .deliver figure:nth-child(3) { animation-delay: 0.8s; }
  .flow.playing .deliver figure.deliver-video { animation-delay: 0s; } /* it plays at once, so it shows at once */
  .flow.playing [data-scene="delivered"] .chips li { animation: flow-in 0.3s ease both calc(1.1s + var(--k) * 0.15s); }
}
@keyframes flow-in { from { opacity: 0; transform: translateY(8px); } }
@keyframes flow-attach { from { opacity: 0; transform: translateY(16px) scale(0.96); } }
@keyframes flow-blink { 50% { opacity: 0; } }
@keyframes flow-wait { 50% { opacity: 0.25; } }

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.chips li { padding: 6px 10px; border: 1px solid var(--line-strong); border-radius: 999px; font-size: 13px; color: var(--fg-2); }

.iso { display: block; width: 100%; height: auto; overflow: visible; }
.iso path { fill: none; }
.iso-shell { stroke: var(--draw); stroke-width: 1.3; stroke-linejoin: round; }
.iso .iso-cut { fill: var(--draw); stroke: var(--draw); stroke-width: 0.6; stroke-linejoin: round; }
.iso-phantom { stroke: var(--dim); stroke-width: 1; stroke-dasharray: 10 3 2 3; }
.iso-hidden { stroke: var(--dim); stroke-width: 1; stroke-dasharray: 4 4; }
.iso-part { stroke: var(--accent-hi); stroke-width: 1.1; }
.iso-dim path, .iso-label path { stroke: var(--dim); stroke-width: 0.8; }
.iso text { font: 12px var(--font-mono); fill: var(--muted); }
.iso-label text { fill: var(--accent-hi); }
@media (max-width: 699px) { .iso text { font-size: 17px; } }
/* Graphite landing sections: the home's audience cards, formats strip, send/get, scope, confidentiality, FAQ and the
   closing call with the waitlist. The example tiles of /work live here too. */

/* The other audiences, right under the home's hero (whose bottom padding spaces them): a card each with its picture,
   its audience, its page's title and a link. Like the example tiles, the link covers the card and the card shows the
   focus ring where :has() works. Three across; under 700px a compact row each. */
.audiences { padding-top: 0; border-top: 0; }
.aud-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.aud-card { position: relative; display: grid; grid-template-rows: auto 1fr; overflow: hidden; border: 1px solid var(--line-strong); border-radius: var(--radius-lg); background: var(--panel); }
.aud-card:hover { border-color: var(--muted); }
.aud-card img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.aud-body { display: flex; flex-direction: column; gap: 8px; padding: 18px 20px 20px; }
.aud-body p { color: var(--fg-2); }
.aud-link { margin-top: auto; padding-top: 6px; font-weight: 500; text-decoration: none; color: var(--accent-hi); }
.aud-link::after { content: ""; position: absolute; inset: 0; }
/* The card takes the link's ring only where :has() works; elsewhere the link keeps its own. */
@supports selector(:has(a)) {
  .aud-card:has(a:focus-visible) { outline: 2px solid var(--accent-hi); outline-offset: 3px; }
  .aud-link:focus-visible { outline: none; }
}
/* Phones: a row about 100px tall, a 112 × 75 thumbnail beside the audience and the link; the page's own title waits
   on the page. */
@media (max-width: 699px) {
  .aud-cards { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .aud-card { display: flex; align-items: center; gap: 14px; padding: 12px; }
  .aud-card img { flex: none; width: 112px; border-radius: 6px; }
  .aud-body { gap: 4px; padding: 0; }
  .aud-body h3 { font-size: 18px; }
  .aud-body p { display: none; }
  .aud-link { margin-top: 0; padding-top: 0; }
}

.formats { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); background: var(--panel); }
.formats-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 40px; padding-block: 18px; font: 13px/1.5 var(--font-mono); color: var(--fg-2); }
.formats .k { margin-right: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--dim); }
.formats + .sec { border-top: 0; }

/* Send and get as an exchange of files: what you send on the left, what you get on the right, a strong arrow between
   them with what we do under it. A row is its format badges and one line; the badges of a side share one column
   (subgrid), so every line of that side starts at the same place. Below 1100px the sides stack, the arrow points
   down and the caption sits beside it. */
.exchange { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: 24px; align-items: center; }
.ex-side { align-self: stretch; padding: 24px 28px 10px; }
.ex-side h3 { padding-bottom: 14px; border-bottom: 1px solid var(--line-strong); }
.ex-rows { display: grid; grid-template-columns: max-content minmax(0, 1fr); column-gap: 20px; margin: 0; padding: 0; list-style: none; }
.ex-rows li { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; align-items: center; padding-block: 16px; border-top: 1px solid var(--line); }
.ex-rows li:first-child { border-top: 0; }
.ex-rows p { font-size: 17px; line-height: 1.45; color: var(--fg); }
.docs { display: flex; gap: 6px; }
.ex-mid { display: grid; justify-items: center; gap: 12px; max-width: 136px; text-align: center; }
.ex-arrow { width: 80px; height: 30px; fill: none; stroke: var(--accent-hi); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.ex-mid p { font-size: 15px; line-height: 1.4; color: var(--fg-2); }
/* A file badge: a small page with a folded corner and its format on it, coloured by its family (format_badges.py).
   The corner is cut off and the fold drawn in its place, so an outline badge is its edge and its fold. */
.doc { position: relative; display: inline-flex; flex: none; align-items: flex-end; justify-content: center; width: 40px; height: 48px; padding-bottom: 8px; border: 1px solid var(--edge); border-radius: 3px; background: var(--fill); color: var(--ink); font: 600 11px/1 var(--font-mono); letter-spacing: 0.02em; clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%); }
.doc::before { content: ""; position: absolute; top: -1px; right: -1px; width: 12px; height: 12px; background: linear-gradient(to bottom left, transparent 50%, var(--fold) 50%); }
.doc-cad { --fill: var(--badge-cad); --ink: var(--badge-ink); --edge: var(--badge-cad); --fold: var(--badge-cad-fold); }
.doc-drawing { --fill: var(--badge-drawing); --ink: var(--badge-ink); --edge: var(--badge-drawing); --fold: var(--badge-drawing-fold); }
.doc-sheet { --fill: var(--badge-sheet); --ink: var(--badge-ink); --edge: var(--badge-sheet); --fold: var(--badge-sheet-fold); }
.doc-image { --fill: var(--badge-image); --ink: var(--badge-ink); --edge: var(--badge-image); --fold: var(--badge-image-fold); }
.doc-text { --fill: transparent; --ink: var(--badge-text-ink); --edge: var(--badge-text-edge); --fold: var(--badge-text-edge); }
@media (max-width: 1099px) {
  .exchange { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .ex-mid { grid-auto-flow: column; align-items: center; justify-self: center; gap: 14px; max-width: none; text-align: left; }
  /* The margins give the turned arrow its own box, 30 wide and 80 tall; without max-width that box would shrink it. */
  .ex-arrow { max-width: none; margin: 25px -25px; transform: rotate(90deg); }
}
/* Phones: three badges beside a line would leave it a narrow column, so a row puts its badges above its line. */
@media (max-width: 639px) {
  .ex-side { padding: 20px 18px 6px; }
  .ex-rows { grid-template-columns: minmax(0, 1fr); }
  .ex-rows li { row-gap: 10px; }
  .ex-rows p { font-size: 16px; }
}

/* What we design: a card per kind, at most 370px wide so its square picture does not swell, the row centred. Two and
   three cards stand in one row and four go 4 across; below 1100px four go 2 + 2, never 3 + 1, and below 800px three
   stack. Phones: one column at full width. The cards of a row share their rows (subgrid), so every title starts on
   one line whatever stands above it. */
.types { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 370px)); justify-content: center; gap: 20px; }
.types[data-count="2"] { grid-template-columns: repeat(2, minmax(0, 370px)); }
.types[data-count="3"] { grid-template-columns: repeat(3, minmax(0, 370px)); }
.types[data-count="4"] { grid-template-columns: repeat(4, minmax(0, 370px)); }
@media (max-width: 1099px) { .types[data-count="4"] { grid-template-columns: repeat(2, minmax(0, 370px)); } }
@media (max-width: 799px) { .types[data-count="3"] { grid-template-columns: minmax(0, 370px); } }
@media (max-width: 699px) { .types, .types[data-count] { grid-template-columns: minmax(0, 1fr); } }
.type-card { display: grid; grid-row: span 4; grid-template-rows: subgrid; row-gap: 12px; padding: 20px; }
/* The picture box. While a kind's assembly drawing is not made, it centres the example's cutaway drawing or its
   concept sketch. */
.type-visual { display: grid; place-items: center; min-height: 220px; padding: 8px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); }
.type-visual .iso { max-height: 240px; }
/* Numbers too small to read at card size stay in the hero drawings. */
.type-visual .iso-dim, .type-visual .iso-label { display: none; }
.type-visual img { width: 100%; border-radius: var(--radius); }
/* A kind's exploded assembly drawing (imagery/scope_pictures.py): the sheet, cut on the poster's own ground, fills the
   box edge to edge under its radius (a dark sheet's ground is --bg, the box's own, so it shows no seam), and a slim
   dark strip under it names the example; the strip takes any height the row leaves over. */
.type-sheet { grid-template-rows: auto 1fr; place-items: stretch; min-height: 0; margin: 0; padding: 0; overflow: hidden; }
.type-sheet img { width: 100%; border-radius: 0; }
.type-sheet figcaption { padding: 8px 12px; border-top: 1px solid var(--line); font-size: 12px; line-height: 1.45; color: var(--muted); text-wrap: balance; }
.type-sheet .mono { color: var(--dim); }
.type-card p { color: var(--fg-2); }
.type-cases { display: grid; align-content: start; gap: 6px; margin: 4px 0 0; padding: 0; list-style: none; font-size: 14px; }
.type-cases a { text-decoration: none; color: var(--fg-2); }
.type-cases a:hover { color: var(--fg); }
.type-cases .mono { margin-right: 6px; color: var(--dim); }
.scope-note { max-width: 70ch; margin: 28px auto 0; text-align: center; color: var(--fg-2); }
.more.center { text-align: center; }

.promises { max-width: 640px; margin: 0 auto; }
.company { margin-top: 20px; text-align: center; font-size: 14px; color: var(--muted); }

.faq { display: grid; gap: 10px; }
.qa summary { position: relative; padding: 18px 48px 18px 20px; font-weight: 500; list-style: none; cursor: pointer; }
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after { content: "+"; position: absolute; top: 50%; right: 20px; transform: translateY(-50%); font-size: 20px; color: var(--muted); }
.qa[open] summary::after { content: "−"; }
.qa p { padding: 0 20px 20px; color: var(--fg-2); }

.cta { text-align: center; }
.cta-box { display: grid; justify-items: center; gap: 18px; }
.cta .actions { justify-content: center; }
.waitlist { display: grid; gap: 12px; width: 100%; margin-top: 32px; padding: 24px; text-align: left; }
.waitlist h3 { font-size: 18px; }
.waitlist p { color: var(--fg-2); }
/* Email, company, role and the button in one row; the role takes the widest column so its longest choice fits. */
.waitlist-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.2fr) auto; gap: 12px; align-items: end; }
.waitlist input, .waitlist select { width: 100%; padding: 10px 12px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--bg); color: var(--fg); font: 16px/1.5 var(--font-body); }
/* The role's first option reads as a placeholder until a role is chosen. */
.waitlist select:invalid { color: var(--muted); }
.waitlist option { color: var(--fg); }
.waitlist [aria-invalid="true"] { border-color: var(--danger); }
@media (max-width: 899px) { .waitlist-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 699px) { .waitlist-row { grid-template-columns: minmax(0, 1fr); } }

.tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.tile { position: relative; display: grid; grid-template-rows: auto 1fr; overflow: hidden; border: 1px solid var(--line-strong); border-radius: var(--radius-lg); background: var(--panel); }
.tile img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.tile-body { display: grid; align-content: start; gap: 8px; padding: 18px 20px 20px; }
.tile-meta { font-size: 13px; color: var(--muted); }
.tile-title { font: 600 19px/1.3 var(--font-head); }
.tile-title a { text-decoration: none; }
.tile-title a::after { content: ""; position: absolute; inset: 0; }
/* The tile takes the link's ring only where :has() works; elsewhere the link keeps its own. */
@supports selector(:has(a)) {
  .tile:has(a:focus-visible) { outline: 2px solid var(--accent-hi); outline-offset: 3px; }
  .tile-title a:focus-visible { outline: none; }
}
.tile p { font-size: 15px; color: var(--fg-2); }
@media (max-width: 999px) { .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 639px) { .tiles { grid-template-columns: minmax(0, 1fr); } }
/* Graphite pages: examples, case, results, request form, terms, 404. */
.page-head { padding-top: 64px; border-top: 0; }
.page-head .wrap { display: grid; gap: 18px; }
.wrap > h2, .two-col h2 { margin-bottom: 24px; }
.filters { justify-content: flex-start; margin: 12px 0 8px; }

/* Case */
.crumbs { display: flex; gap: 8px; font-size: 14px; color: var(--muted); }
.crumbs a { text-decoration: none; color: var(--fg-2); }
.case-top { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 24px; align-items: start; margin-top: 8px; }
.case-figure { margin: 0; padding: 8px; }
.case-figure img { width: 100%; border-radius: var(--radius); }
.spec { display: grid; margin: 0; border: 1px solid var(--line-strong); border-radius: var(--radius-lg); }
.spec div { display: grid; grid-template-columns: 120px minmax(0, 1fr); gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.spec div:last-child { border-bottom: 0; }
.spec dt { font: 12px/1.6 var(--font-mono); letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
.spec dd { margin: 0; }
.note { max-width: 80ch; font-size: 15px; color: var(--fg-2); }
.note b { margin-right: 8px; color: var(--fg); }
.brief-grid { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 24px; align-items: start; }
.quote { margin: 0; padding: 24px 28px; font: 400 16px/1.75 var(--font-mono); white-space: pre-wrap; overflow-wrap: anywhere; color: var(--fg-2); }
.brief-side { display: grid; gap: 12px; }
.sketch { display: grid; gap: 8px; margin: 0; padding: 8px; }
.sketch img { width: 100%; border-radius: var(--radius); }
.links { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
.links li { display: grid; gap: 2px; }
.links a { font-weight: 500; }
.table td p { margin-top: 4px; font-size: 14px; color: var(--fg-2); }
.table .mono { color: var(--dim); }
.two-col { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px; align-items: start; }
.box { display: grid; gap: 12px; padding: 24px; }
.box p { color: var(--fg-2); }
.plain { display: grid; gap: 8px; margin: 0; padding-left: 18px; color: var(--fg-2); }
.pending { border-style: dashed; }
.pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; }
.pager > a:not(.btn) { text-decoration: none; color: var(--fg-2); }
@media (max-width: 899px) {
  .case-top, .brief-grid, .two-col { grid-template-columns: minmax(0, 1fr); }
}

/* Engine results on a case page */
.flow-scroll { overflow-x: auto; padding-bottom: 8px; }
.results { display: grid; grid-template-columns: repeat(5, minmax(220px, 1fr)); gap: 12px; min-width: 1140px; margin: 0; padding: 0; list-style: none; }
.results > li { display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 16px; }
.results img { width: 100%; aspect-ratio: 3 / 2; object-fit: contain; border-radius: var(--radius); background: var(--bg); }
.results img.cad { aspect-ratio: 1; }
.r-t { font-size: 15px; font-weight: 500; line-height: 1.4; }
.r-s { font-size: 13px; line-height: 1.5; color: var(--muted); }
.r-s b { color: var(--fg); }
.r-list { display: grid; gap: 4px; margin: 0; padding-left: 16px; font-size: 13px; line-height: 1.45; color: var(--fg-2); }
.r-stats { display: grid; gap: 6px; font-size: 14px; color: var(--fg-2); }
.r-stats b { margin-right: 4px; font: 600 18px var(--font-mono); color: var(--fg); }
.r-verdict { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.r-verdict div { display: flex; flex-direction: column; gap: 2px; padding: 8px 6px; border: 1px solid var(--line-strong); border-radius: var(--radius); }
.r-verdict b { font: 600 22px/1 var(--font-mono); font-variant-numeric: tabular-nums; color: var(--fg); }
.r-verdict b.ok { color: var(--accent-hi); }
.r-verdict b.bad { color: var(--danger); }
.r-verdict span { font-size: 11px; line-height: 1.2; color: var(--muted); }
.r-verdict .na { border-style: dashed; }
.r-list .r-more { margin-left: -16px; list-style: none; font-style: italic; color: var(--muted); }
.r-notes { display: grid; gap: 10px; margin-top: 16px; padding: 20px 22px; border-color: var(--danger); }
/* Tablets and phones: the five steps stack, so the verdict falls in normal reading order. */
@media (max-width: 899px) {
  .flow-scroll { overflow-x: visible; }
  .results { grid-template-columns: minmax(0, 1fr); min-width: 0; }
}
.r-warn { color: var(--danger); }
.r-notes ul { display: grid; gap: 6px; margin: 0; padding-left: 18px; font-size: 15px; color: var(--fg-2); }

/* Request form */
.intake { display: grid; gap: 20px; margin-top: 12px; padding: 28px; }
.row2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.field { display: grid; gap: 8px; }
.field label { font-weight: 500; }
.field small { font-size: 14px; color: var(--muted); }
.intake input, .intake select, .intake textarea { width: 100%; padding: 10px 12px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--bg); color: var(--fg); font: 16px/1.5 var(--font-body); }
.intake textarea { min-height: 160px; resize: vertical; }
/* (0,2,0): outranks the field style above, (0,1,1). */
.intake [aria-invalid="true"] { border-color: var(--danger); }
.notice { min-height: 1.6em; color: var(--fg-2); }
.promise-lines { display: grid; gap: 4px; margin: 0; padding-left: 18px; font-size: 14px; color: var(--muted); }
@media (max-width: 699px) { .row2 { grid-template-columns: minmax(0, 1fr); } }

/* Attachments: the send side of a message composer. The zone opens the picker and takes dropped files, and lists
   them inside itself; the script hides the plain file input (without it the input shows). */
.field-title { font-weight: 500; }
.drop { position: relative; display: grid; padding: 6px; border: 1px dashed var(--line-strong); border-radius: var(--radius-lg); background: var(--panel); }
.drop.is-over { border-color: var(--accent-hi); background: var(--bg); }
.drop:has(input:focus-visible) { outline: 2px solid var(--accent-hi); outline-offset: 3px; }
/* Without :has() the zone cannot ring itself and the input is hidden, so the label after it takes the ring. */
@supports not selector(:has(a)) { .drop input:focus-visible + .drop-label { outline: 2px solid var(--accent-hi); outline-offset: 2px; } }
.js .drop input[type="file"] { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; opacity: 0; }
.drop-label { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 10px 12px; font-weight: 400; color: var(--fg-2); cursor: pointer; }
.drop-icon { flex: none; width: 24px; height: 24px; fill: none; stroke: var(--muted); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.drop-choose { color: var(--accent-hi); text-decoration: underline; text-underline-offset: 3px; }
.drop-label:hover .drop-choose { color: var(--fg); }
.file-list { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 2px 6px 6px; list-style: none; }
.file-list:empty { padding: 0; } /* shown at no height, not hidden, so the live list announces the first file */
.file-list li { display: grid; grid-template: "thumb name remove" auto "thumb size remove" auto / 48px minmax(0, 1fr) auto; align-items: center; column-gap: 10px; flex: 0 1 260px; min-width: 0; padding: 6px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--bg); }
.file-thumb, .file-glyph { width: 48px; height: 48px; grid-area: thumb; border-radius: 6px; }
.file-thumb { object-fit: cover; }
.file-glyph { display: grid; place-items: center; border: 1px solid var(--line-strong); background: linear-gradient(225deg, var(--line-strong) 0 9px, transparent 9px); font: 500 11px/1 var(--font-mono); text-transform: uppercase; color: var(--muted); }
.file-name { grid-area: name; align-self: end; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; color: var(--fg); }
.file-size { grid-area: size; align-self: start; font: 12px/1.5 var(--font-mono); color: var(--muted); }
.file-remove { grid-area: remove; width: 32px; height: 32px; border: 0; border-radius: var(--radius); background: transparent; color: var(--muted); font: 20px/1 var(--font-body); cursor: pointer; }
.file-remove:hover { background: var(--line-strong); color: var(--fg); }
