/* Hallmark · genre: editorial · macrostructure: Split Studio
 * H2 diptych knobs: ratio=7/5 · right=proof column · divider=negative space
 * theme: custom (tuned) · vibe: "sharp, premium, ink on paper, unfussy"
 * paper: oklch(95.8% 0 0) #f1f1f1 · accent: oklch(50% 0.200 268) #3453d3 (ultramarine since 2026-09-28; was vermilion on warm paper)
 * display: Aeonik Pro 500 · body: Inter · labels: Geist Mono · wordmark: Fraunces (ToDesktop's type, 2026-09-29)
 * axes: light / roman-serif / neutral · nav: N9 edge-aligned · footer: Ft1 mast-headed
 * enrichment: Tier-A CSS specimens — the case comparators (the switch, which replaced the spec sheet, was removed 2026-09-22)
 * studied: no · context: brief + inferred · pre-emit critique: P5 H5 E4 S5 R4 V5
 *
 * CAPABILITIES (2026-09-21) · studied: yes · DNA-source: url (squarespace.com
 * "Grow your business") — concept only: tabs + peek carousel of 16:10 drawn
 * sample cards; no stock photography, no copied styling.
 *
 * SURFACE PASS (2026-09-21) · studied: yes · DNA-source: url (squarespace.com,
 * wix.com, read live) — rhythm only: day / dusk fade / night / day / night.
 * Night is a token remap (.on-ink); glows are --color-glow-day / -night.
 *
 * VISUAL PASS (2026-09-16) — the page sold visual transformation and argued for
 * it entirely in prose: half its height was head + hairline + rows of text, and
 * the only two sections that were not text were iframes of other people's work.
 * Four sections now perform their claim instead of describing it:
 *   · the spec sheet  — five live specimen pairs, generic boxed, ours on paper
 *   · the process     — four steps drawn to the time they actually take
 *   · the offer       — ruled terms, and the pay-when-satisfied promise at rank
 *   · the argument    — the method stated in two hard-broken lines
 * #case, the interlude, the form, nav and footer were already carrying the
 * visual load and were not touched.
 *
 * #build (2026-09-17) turned out NOT to be carrying it. Measured: 174 words in
 * eight definition rows, 591px of prose before the first visual, and the live
 * frame at 19.3% of the section inside a 7/5 grid. The cause was structural —
 * #case works because it is a diptych and the comparison IS the argument;
 * #build has no "before" by definition, inherited that shape without the
 * mechanism, and filled the gap with prose. Now: the whole brief as one line
 * under the heading, then the frame at full width, then four rows. 591 -> 265px
 * of prose, frame 19.3% -> 36.4%, section 1450 -> 1568px.
 *   Cut and why: CAME WITH / ASKED FOR became the one-line brief. KEPT ("their
 *   photography, not one frame of stock") went with it. HAD TO SHOW — the GSK /
 *   Johnson Controls / Movenpick list — is cut and should not return as a logo
 *   wall: they are EURODECOR'S clients, and the more visual this page makes
 *   them the more they read as ours.
 *   The folder took two attempts. Take 1 showed eight of their photographs at
 *   ~300px and measured WORSE than doing nothing: +400px, and the frame's
 *   share fell to 16.4% — below where it started. It also read as a portfolio,
 *   spending half the section on finished, beautifully shot interiors right
 *   before asking the reader to judge our website, under a heading that says
 *   there was nothing to improve. Take 2 kept the photographs and changed only
 *   the SCALE: a contact sheet at ~80px, where you read quantity and texture
 *   rather than stopping on a lobby. +203px, frame share 32.2%. Shipped.
 *   If it is ever revisited: the scale is the load-bearing decision, not the
 *   pictures. Enlarging the cards re-creates take 1.
 *
 *   Then the frame itself went compact (Squarespace's ~62% of viewport, not the
 *   full shell — 1168x657 read as a slab) and the margins it freed were filled
 *   with the fit-out sequence: stage 01 and stage 15, same room, same camera.
 *   Section 1808 -> 1610px WITH two more images in it.
 *   OPEN QUESTION left deliberately: the contact sheet and the triptych are now
 *   both EuroDecor photography doing overlapping work, and the triptych is the
 *   stronger of the two because it can show NOTHING (a bare shell), which is
 *   what the heading promises. Dropping the folder takes the section to ~1400.
 *
 * REMOVED 2026-09-22: the folder (contact sheet + logo tile) is gone. The notes
 *   below are history; the brief alone is the input now.
 * THE LOGO (2026-09-21). The sub-line promises three inputs — a folder of
 *   photography, a logo, a one-line brief — and the page showed two of them:
 *   the contact sheet IS the folder, the pull-quote IS the brief. The logo was
 *   the only one merely asserted. It now sits as the first tile in the folder.
 *   Considered and rejected: swapping the <h3>EuroDecor</h3> for the logo. The
 *   h3 is a LABEL in our voice and our type; the logo is MATERIAL we were
 *   handed. Putting material at title rank makes the client's brand the crown
 *   of a section about our work — the same error that got the fit-out sequence
 *   pulled. Keep the h3.
 *   Cost, and a trap worth naming: the sheet must end on a WHOLE ROW or it
 *   leaves a stub with dead space beside it. The 14-column base had no trim
 *   because 28 photographs were exactly two rows — the logo's 3 cells broke
 *   that silently, and the first fix only retuned the 7- and 4-column queries,
 *   so the widest viewport (the common one) was the one left ragged. If the
 *   logo's span or the photo count ever changes, re-check ALL THREE tiers.
 *   Settled: 3 + 11 = 14 (one row at 14 cols, two at 7, one shared n+13 cutoff
 *   on the base rule) and 3 + 9 = 12 at 4 cols. 28 -> 11 photographs is also
 *   the deliberately minimal count: at 14 columns 28 read as a dump, and the
 *   single strip says "a folder of material" without asking to be browsed.
 *   Verified whole rows, no overflow, and logo row height equal to the photo
 *   rows at 320 / 375 / 640 / 900 / 1000 / 1440 / 2000.
 *   RIGHTS, on the record: EuroDecor publish white-on-dark only. This asset is
 *   their wordmark RECOLOURED by us to --color-ink with the yellow untouched —
 *   a variant they do not publish and have not seen. The owner decided on
 *   2026-09-21 to ship it without asking them, having been told twice. That is
 *   a decision taken, NOT permission granted; do not record it as cleared.
 *
 * RUNNING ORDER (2026-09-16) — proof moved to the front. #case now sits directly
 * behind the hero: the claim is that the site is forgettable, and the fastest
 * answer to "says who" is two versions of a real one side by side. The spec
 * sheet fell in behind the argument, where it works as the itemised reading of
 * what the reader has just watched happen twice. Order is: hero · redesigned ·
 * built from scratch · argument (interlude cut 2026-09-21) · what changes · process · offer ·
 * ask. Note this mounts ~15 MB of BizArch mirror close to first paint — the
 * frames are lazy and don't block the hero, but the bandwidth is spent on
 * every visitor, including one who bounces at the fold.
 *
 * TYPE SCALE (2026-09-16) — tracking and leading were single constants applied
 * from 84 px down to 20 px: -0.025em and 1.05 everywhere, plus a dozen ad-hoc
 * overrides that didn't agree with each other. Both are now functions of
 * rendered size (--track-* / --leading-* in tokens.css), and any element that
 * changes size at a breakpoint changes tier with it. Display stops at -0.042em,
 * not the -0.06em a geometric sans would take: Fraunces is high-contrast and
 * its hairlines start colliding with neighbouring stems past about -0.045em.
 *
 * Gates — contrast: pass (40–41, 132/132 text nodes, focus ring 5.57:1)
 *         nav/footer/hero: pass (42–45) · honest: pass (46, no invented metrics)
 *         chrome: pass (47) · tokens: pass (48) · responsive: pass (49)
 *         mobile: pass (34, 49, 50–57 at 320/375/414/768)
 *
 * CASE COMPARATOR — four cases in one component, tabbed.
 *   Sync is by proportional fraction, not absolute pixels: paired documents run
 *   to different scroll extents, so matching fractions holds them at the same
 *   point in their own narrative. Lazy-mounted 600px before entry so an older
 *   site's splash finishes off-screen. Below 48rem the frames stop scaling and
 *   each site renders its OWN mobile layout — the comparison a phone visitor
 *   actually cares about. Measured 61 fps while both scroll.
 *   Two modes, and the difference is stated to the visitor rather than faked:
 *     local + local  → scroll-linked, scrubber shown (BizArch, Ayah Kutub)
 *     local + live   → cross-origin, unreachable scroll, so the scrubber is
 *                      withdrawn and both panels scroll individually
 *                      (Ayah Kutub, EuroDecor)
 *   Frames are RECREATED per case: sandbox flags latch onto the current
 *   document, so a local case loaded after a live one stays opaque otherwise.
 *   Tabs are <button>s, never the CSS radio pattern, which scroll-jumps (gate 53).
 *   Chosen over recorded video, which cannot be produced in this environment
 *   and would rot on every client update.
 *
 * OFFER POSTURE — the guarantee is stated ONCE, in the offer's Invoice row.
 *   It previously appeared five times across hero, process, terms, Q&A and CTA;
 *   a promise repeated five times reads as pleading regardless of wording, and
 *   rewording it without cutting the count fixes nothing. Framed as the studio's
 *   own standard ("we don't invoice work we wouldn't put our name on") rather
 *   than the client's protection ("you pay when you're satisfied") — same terms,
 *   opposite posture. Also removed: "how a new studio earns its first clients",
 *   which announced inexperience directly above four delivered projects.
 * PRICE — deliberately absent. No figure, no floor, no "from" range. The
 *   pay-when-satisfied term already carries the risk a price tag exists to
 *   settle, so a posted number only drags the cost conversation earlier —
 *   before the prospect has seen their own site redesigned, and into a
 *   comparison with the template market that this positioning exists to
 *   escape. The fourth term answers WHEN ("Before day one"), not WHAT, so the
 *   absence reads as an invitation rather than a hole -- the Price term is a
 *   link to the form, not a statement. "Before day one" moved into the QA and
 *   the ask, where the reassurance still lands. Not a tier table either:
 *   there is one service, and a Starter/Pro grid would misrepresent it.
 *   Do not restore a figure without an explicit decision to.
 * INTERLUDE — one full-bleed line, once, after the cases. Left-aligned to the
 *   page spine; centring it would read as borrowed from the source it came from.
 *
 * FEATURED BUILD — the input→output card, adapted from usehallmark.com's verb
 *   cards. Their shape is prompt → arrow → artefact → spec. Ours is brief →
 *   arrow → the live site → spec, because a from-scratch case has no "before"
 *   to put on the left. Taken: the spec rows, above all REFUSED — refusal
 *   stated structurally rather than only in tone. Dropped: their screenshot
 *   (we have live sites, an image would be a downgrade) and their bordered
 *   rounded card (card-in-card against our hairline register).
 *   The hero now carries a second door — a from-scratch case in a page whose
 *   headline assumes you already have a site would turn away the exact visitor
 *   it then proves itself to. The form's "I don't have one yet" is the other
 *   half: inviting them and then rejecting them at the field is worse than
 *   not inviting them.
 *
 * STUDY — hallmark study https://www.usehallmark.com/ (2026-08-31).
 *   DNA was adopted SELECTIVELY, not wholesale: the source is a dev-tool
 *   product site (Plus Jakarta Sans + JetBrains Mono, npx block, GitHub star
 *   count) selling 20 themes to developers. This page sells one human
 *   judgment to Saudi SME owners, so its type, palette and genre are NOT the
 *   source's and must not drift toward them.
 *   Taken:    the shared input stated before the comparison (.source);
 *             a hairline rule under every section head (.head-rule);
 *             0.5px hairlines, guarded to >=2dppx.
 *   Declined: the theme switcher (their product is variation; ours is a single
 *             considered result — a randomiser would argue against the pitch);
 *             their type + palette; per-section ordinal eyebrows (ours are not
 *             ordinal); the craft-naming caption (design jargon for an audience
 *             that does not speak it, and it duplicates the section beneath).
 *
 * HERO — H9 CENTREPIECE OBJECT over a centred marquee. Studied from mobbin.com
 *   (composition only; none of its type, none of its palette, and none of its
 *   floating app icons). What transfers from that reference is not the icons —
 *   it is that one small TYPE-FREE object sits above the headline in a lot of
 *   air. A page is type-dense and collides with a headline; an object of this
 *   size cannot. What did NOT transfer, deliberately: the logo/proof row (we
 *   hold three cases and one build — four logos is thin, two of those
 *   engagements are not closed, and it is "trusted by N teams" in a costume),
 *   the pill radii, and the single-family geometric sans.
 *
 *   The object is a DECK of three blank sheets that square themselves into
 *   register, after which the vermilion mark presses on like a stamp. Blank
 *   paper, not re-drawn browser chrome. The gesture is the argument: loose
 *   work becomes composed work, and the correction mark signs it.
 *
 *   Cost paid knowingly: the axis is centred, so the hero no longer shares a
 *   left edge with the sections beneath it. That is a real loss of continuity,
 *   accepted because the object needs somewhere to sit and a left-biased
 *   version put it in the corner.
 *
 *   THE LEDGER IS GONE. Four rows of "Generic → Premium" was a compressed
 *   version of the spec sheet, which demonstrates its claims instead of
 *   asserting them. Keeping both said the same thing twice.
 *   Its history is preserved below because the reasons still bind: the rows
 *   were four DISTINCT axes, not four synonyms, and OUTDATED → Modern was cut
 *   because it contradicts the headline (the claim is that the site is NOT
 *   broken) and because "modern" is the word every agency uses — it was also
 *   EuroDecor's own brief language, quoted on this page as the CLIENT's words.
 *
 *   Rejected in this slot, recorded so they are not re-proposed:
 *     an animated 12-block "settle" — an abstraction must be decoded and a hero
 *       has ~2s; it read as "a black box and some lines". The slot now holds
 *       the service deck (2026-09-28): seven recognisable icons, one at a
 *       time, nothing to decode. Before it: "square up, then stamp" sheets.
 *     a 4-site contact sheet — played the whole showreel in the first viewport,
 *       leaving `Redesigned.` nothing to reveal, and put OUR portfolio where the
 *       visitor is thinking about THEIR site. "A trailer showing the whole film."
 *     a working URL field ("the front door") — the only version where the hero
 *       did a job, but it asked for the visitor's site before showing them
 *       anything: a box office with no poster. Removed with its CSS and its
 *       frontDoor IIFE; #send remains the only intake.
 *     a mini live GENERIC|LAYOUTICS specimen — the squeeze IS the argument and
 *       it cannot survive 230px panes; shrinking it removes the mechanism that
 *       made it good, leaving a taste-claim in a small box.
 *     a real client BEFORE as the hero image — best conceptual fit (show the
 *       problem, withhold the resolution) but every before belongs to a NAMED
 *       client, and making one the poster-child for "forgettable" is a public
 *       judgement on a company that hired us. Not built.
 *     four full-page directions (subtract / full-bleed / split / ink ground)
 *       and a macro-crop study — all rejected. The finding worth keeping from
 *       them: a headline over a live website does not work. Weak scrim and our
 *       headline collides with the framed site's own headline; strong scrim and
 *       the site disappears and you have built a black rectangle at the cost of
 *       15 MB. There is no setting in between. That is a property of the medium.
 *   Loose finding for any future display headline: the global h1 rule sets
 *   text-wrap: balance, which evens lines and can leave the ink well short of
 *   the measure. The reset is `text-wrap: wrap` — `normal` is not in that
 *   shorthand's grammar and is silently dropped.
 *
 * NOTE — the page no longer quotes any anti-pattern. The live 'generic'
 *   specimen that carried the scoped exceptions (gates 2, 3, 7, 30, 37) was
 *   cut once four real case studies made a simulated one redundant.
 */

/* ============================================================ base */

*, *::before, *::after { box-sizing: border-box; }

html {
  overflow-x: clip;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* .nav is sticky at top:0 and 77px tall at every width, so without this every
     in-page jump parks the target's first line underneath it — "See the work",
     "We build from scratch too", "On request", the nav button and all four
     footer links landed with ~13px of their heading clipped. 6.5rem clears the
     nav with about space-lg of air beneath it. Raise it if the nav grows. */
  scroll-padding-top: 90px;   /* the bar is 82px since the floating-pill nav (2026-09-29); was 6.5rem */
}

body {
  overflow-x: clip;
  margin: 0;
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 400;
  line-height: 1.625;   /* 16/26, theirs */
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  padding-inline: max(0px, env(safe-area-inset-left));
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-style: normal;
  /* Fraunces' opsz is a true optical size (9-144), not a weight knob. The high
     grades are drawn for poster use and their hairlines go sub-pixel when set
     small — headings here span 20px to 61px, so one fixed grade cannot serve
     them all. The default suits display sizes; anything smaller sets --opsz
     next to its font-size. Rule of thumb: opsz roughly tracks rendered px,
     with up to ~1.5x headroom for display character. */
  font-variation-settings: "opsz" var(--opsz, 144), "SOFT" 0, "WONK" 0;
  font-weight: 500;   /* Aeonik Pro Medium, as ToDesktop sets every heading */
  line-height: var(--leading, var(--leading-snug));
  letter-spacing: var(--track, var(--track-md));
  overflow-wrap: anywhere;
  min-width: 0;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0; }
ul, ol, dl, dd { margin: 0; padding: 0; }
li { list-style: none; }

a { color: inherit; }

img, svg { max-width: 100%; display: block; }

:focus-visible {
  outline: var(--rule-bold) solid var(--color-focus);
  outline-offset: 3px;
  border-radius: var(--radius-md);
}

::selection { background: var(--color-accent); color: var(--color-accent-ink); }

/* display on .tlink / .foot__link would otherwise beat the UA's [hidden] rule. */
[hidden] { display: none !important; }

.vh {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ============================================================ layout */

.shell {
  width: 100%;
  max-width: 84rem;
  margin-inline: auto;
  padding-inline: var(--page-gutter);
}

.band { padding-block: var(--space-3xl); }
.band--tight { padding-block: var(--space-2xl); }
.band--tall { padding-block: var(--space-4xl) var(--space-3xl); }
.band + .band { border-block-start: var(--rule-hair) solid var(--color-rule); }

/* Section heads — always a single column, tag stacked above the heading. */
.head { display: flex; flex-direction: column; gap: var(--space-sm); max-width: 46ch; }
.head__title { font-size: var(--text-2xl); --opsz: 72; --track: var(--track-lg); }
.head__sub { color: var(--color-ink-2); font-size: var(--text-md); line-height: 1.5; max-width: 46ch; text-wrap: balance; }
/* phones: body size, one line, as the Services sub (2026-09-28). At 20px
   "Same business, same content, new bones." left "bones." alone, and
   balancing split it as "same / content". */
@media (max-width: 40rem) { .head__sub { font-size: var(--text-base); } }

.tag {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

.rule { border: 0; border-block-start: var(--rule-hair) solid var(--color-rule); margin: 0; }
/* The head is capped at 46ch for measure; its rule runs the full column. */
.head-rule { margin-block-start: var(--space-lg); }

/* ============================================================ buttons + links */

.btn {
  --btn-bg: var(--color-ink);
  --btn-fg: var(--color-paper);
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  white-space: nowrap;
  padding: 0.9rem 1.4rem;
  min-height: 48px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: var(--rule-hair) solid var(--color-ink);
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  letter-spacing: -0.005em;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-short) var(--ease-out),
              color var(--dur-short) var(--ease-out),
              transform var(--dur-micro) var(--ease-out);
}
.btn:hover { --btn-bg: var(--color-accent-deep); border-color: var(--color-accent-deep); transform: translateY(-1.5px); }
.btn:active { transform: translateY(0); transition-duration: 60ms; }

.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--color-ink);
  border-color: var(--color-rule);
}
.btn--ghost:hover { --btn-bg: transparent; --btn-fg: var(--color-accent-deep); border-color: var(--color-accent); }

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
  --btn-bg: var(--color-ink);
  --btn-fg: var(--color-paper);
}
.form__submit:disabled { --btn-bg: var(--color-paper-3); --btn-fg: var(--color-muted); border-color: var(--color-paper-3); }

/* Typographic CTA — a drawn underline, not a gradient. */
/* The underline tracks the text, not the box — so the hit target can grow to
   44 px without the rule drifting away from the words. */
.tlink {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  min-height: 44px;
  white-space: nowrap;
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--color-rule);
  text-decoration-thickness: 1px;
  text-underline-offset: 5px;
  transition: text-decoration-color var(--dur-short) var(--ease-out),
              text-decoration-thickness var(--dur-short) var(--ease-out),
              color var(--dur-short) var(--ease-out);
}
.tlink:hover {
  color: var(--color-accent-deep);
  text-decoration-color: var(--color-accent);
  text-decoration-thickness: 2px;
}

/* ============================================================ N9 · edge-aligned nav */

.nav {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: color-mix(in oklab, var(--color-paper) 88%, transparent);
  backdrop-filter: blur(10px);
  border-block-end: var(--rule-hair) solid transparent;
  transition: border-color var(--dur-short) var(--ease-out);
}
.nav[data-stuck="true"] { border-block-end-color: var(--color-rule); }
.nav__inner {
  /* three columns so the link pill sits at the true centre whatever the
     wordmark and button widths are (Bento's nav, 2026-09-28) */
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--space-md);
  padding-block: var(--space-md);
}
/* pinned to their columns: on phones the links are display:none, and the
   button would otherwise auto-place into the empty middle, beside the wordmark */
.nav__inner > .wordmark { grid-column: 1; justify-self: start; }
.nav__links { grid-column: 2; }
.nav__inner > .nav__cta { grid-column: 3; justify-self: end; }
/* Fraunces' opsz axis is a real optical size, not a style knob: the high
   grades are drawn for poster sizes and their hairlines fall under a pixel
   when set small — at 96 the wordmark's `t` crossbar and terminals simply
   disappear. Track the axis to the rendered size (24 at ~25 px), and take
   the size up one step so 600-weight serif can hold its own beside a filled
   button, which carries far more visual mass than its point size suggests. */
.wordmark {
  font-family: var(--font-brand);
  font-variation-settings: "opsz" 24, "SOFT" 0, "WONK" 0;
  font-weight: 600;
  font-size: var(--text-lg);
  letter-spacing: var(--track-sm);
  text-decoration: none;
  white-space: nowrap;
}
.wordmark::after {
  content: "";
  display: inline-block;
  inline-size: 6px; block-size: 6px;
  margin-inline-start: 4px;
  background: var(--color-accent);
  vertical-align: 0.06em;
}
.nav__cta { font-size: var(--text-nav); padding: 0.65rem 1.15rem; min-height: 44px; border-radius: 999px; }
.nav__cta { transition: opacity var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out), visibility 0s; }
.nav[data-cta="held"] .nav__cta {
  opacity: 0; visibility: hidden; transform: translateY(-4px);
  transition: opacity var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out), visibility 0s var(--dur-short);
}
@media (prefers-reduced-motion: reduce) { .nav__cta, .nav[data-cta="held"] .nav__cta { transition: none; transform: none; } }
/* section links: only where there is room for them beside the button;
   on smaller screens the page is one scroll and the button is the nav.
   The Bento nav (owner's reference, 2026-09-28): the links in one white pill
   floating on the grey, sentence case in grey, and a softer grey pill behind
   the section being read (app.js sets aria-current as you scroll). Replaced
   14px caps with an underline on hover (the Squarespace measure, 2026-09-22).
   Rounded on purpose: the site is moving off square corners. */
.nav__links {
  display: none; gap: 2px; padding: 4px;
  background: var(--color-card);
  border: var(--rule-hair) solid var(--color-rule-2);
  border-radius: 999px;
  box-shadow: 0 8px 24px oklch(20% 0.005 270 / 0.07), 0 1px 2px oklch(20% 0.005 270 / 0.05);
}
.nav__link {
  display: inline-flex; align-items: center; min-height: 40px;
  padding-inline: 1.15rem; border-radius: 999px;
  white-space: nowrap; color: var(--color-muted); text-decoration: none;
  font-size: var(--text-nav); font-weight: 400; line-height: 20px; letter-spacing: 0;   /* 14px, was 12.8: the smallest clickable text on the page under 16px tabs (2026-09-28) */
  transition: background-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out);
}
.nav__link:hover { color: var(--color-ink); background: var(--color-paper); }
.nav__link[aria-current="true"] { color: var(--color-ink); background: var(--color-pill); }
.nav__link:focus-visible { outline: var(--rule-bold) solid var(--color-focus); outline-offset: 2px; }
@media (min-width: 60rem) { .nav__links { display: flex; } }

/* ============================================================ hero · H9 centrepiece + centred marquee

   Studied from mobbin.com's hero (composition only — none of its type, none of
   its palette). The transferable move there is not the floating app icons, it
   is that ONE small type-free object sits above the headline in a lot of air.
   A page is type-dense and collides with a headline; an object this size
   cannot. That is the property being borrowed.

   The ledger is gone with the split. Four rows of "Generic → Premium" was a
   compressed version of the spec sheet, which now DEMONSTRATES all eight of
   those claims instead of asserting four — keeping both said the same thing
   twice. The axis is centred rather than left-biased, which is a real cost:
   the hero no longer shares a left edge with every section under it. Traded
   knowingly for the object having somewhere to sit. */

/* Padding-top is space-2xl, NOT space-3xl. The extra 32px was costing the
   from-scratch link at the bottom of the hero its place above the fold on a
   13" laptop, and the sticky nav already puts 77px of air over the object.
   Don't "restore" it — the air that matters here is AROUND the object, and
   that comes from the object's own margins, not from the section's lid. */
.hero { padding-block: var(--space-2xl) var(--space-3xl); }
.hero__inner { max-inline-size: 58rem; margin-inline: auto; text-align: center; }

.hero__display {
  font-size: var(--text-display);
  --track: var(--track-display);
  --leading: var(--leading-display);
  max-width: 20ch;
  margin-inline: auto;
}
.hero__display em { font-style: normal; color: var(--color-accent); }
/* Two clauses, hard-broken, in the manner of the reference: what it is, then
   the term. The break is deliberate — 48ch holds the longer clause on one line
   at every width above 40rem, so neither half ever wraps on its own. */
.hero__lede {
  margin-block-start: var(--space-lg);
  font-size: var(--text-md);
  line-height: 1.5;
  color: var(--color-ink-2);
  max-width: 48ch;
  margin-inline: auto;
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-md);
  margin-block-start: var(--space-lg);
}
.hero__alt { margin-block-start: var(--space-lg); font-size: var(--text-nav); color: var(--color-muted); }   /* 14px, was 12.8: the one door for visitors without a site, under 16px buttons (2026-09-28) */
@media (max-width: 40rem) { .hero__alt { font-size: var(--text-sm); } }   /* phones keep 12.8: one line at 375; at 14 it wrapped and the link's 44px tap box opened a gap between the lines */

/* ---- the centrepiece — the service deck (2026-09-28, owner) ------------
   Mobbin's hero mechanism, measured in their page: a stack of three app-icon
   tiles, the back two smaller and peeking above as plain grey sheets; about
   every 4s the front tile drops and fades, the others step forward and take
   their colour, and a new one arrives at the back. Ours carries the seven
   services, drawn as SVG in the palette (blue / ink / white tiles, the
   lighter blue as the accent on the dark two). It replaced the "square up,
   then stamp" sheets and their pointer tilt: a cycling stack plus tilt was
   too much motion for one small object.

   app.js sets data-slot on each tile: 0 front, 1 and 2 behind, "out" leaving,
   none = waiting unseen at the back. Transform and opacity only. The origin
   is the top edge, so a smaller tile keeps its top where translateY puts it,
   8px higher per step, and shows as a sliver above the one in front.
   aria-hidden: the headline and the Services section say it in words. */
.hero__object {
  margin-block-end: var(--space-lg);
  block-size: 158px;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
}
/* The front tile's name, in step with the shuffle (owner, 2026-09-28: the
   icons alone read as a guessing game). One caption under the stack, not
   words on 92px tiles. */
.deck__label {
  margin-block-start: 0.9rem; min-block-size: 1.2em;
  font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--color-muted);
  transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out);
}
.deck__label.is-swap { opacity: 0; transform: translateY(3px); }

.deck { position: relative; inline-size: 92px; block-size: 92px; }

.deck__tile {
  /* Three glass tiles (2026-09-28). First solid blue / ink / white tiles
     (the owner: flashy), then all-white milk glass with gradient icons
     (the owner: repetitive, boring). This blends them: the three colours
     are back, so each shuffle changes, and every tile has the glass
     finish from the owner's references: a top-lit gradient, a sheen on the
     upper half, a bright rim, an inner shade at the foot and a soft
     floating shadow. Icons are solid (white on blue and ink, ink on
     white, one accent detail each); only AI agents gets gradients (t-ai
     below). Not the references' rainbow: our one accent is blue. */
  --top: oklch(62% 0.15 266); --bot: oklch(46% 0.19 266);
  --sheen: 0.18; --edge: 0.5; --ring: 0.12; --shade: 0.16;
  --glow: transparent; --glow-at: 50% 50%;
  --stroke: #fff; --fg: #fff; --acc: oklch(88% 0.06 272); --cut: oklch(49% 0.19 266);
  position: absolute; inset: 0; display: grid; place-items: center;
  border-radius: 28%;
  background:
    linear-gradient(180deg, oklch(100% 0 0 / var(--sheen)) 0%, oklch(100% 0 0 / 0) 52%),
    linear-gradient(180deg, var(--top), var(--bot));
  box-shadow:
    inset 0 1px 0 oklch(100% 0 0 / var(--edge)),
    inset 0 0 0 1px oklch(100% 0 0 / var(--ring)),
    inset 0 -3px 8px oklch(0% 0 0 / var(--shade)),
    0 0 0 0.5px oklch(25% 0.01 270 / 0.10),
    0 2px 4px oklch(25% 0.01 270 / 0.06),
    0 16px 30px -10px oklch(28% 0.04 270 / 0.28);
  transform-origin: 50% 0;
  transform: translateY(-26px) scale(0.52);
  opacity: 0; z-index: 0;
  transition:
    transform 620ms cubic-bezier(0.34, 1.28, 0.5, 1),
    opacity 320ms var(--ease-out);
}
.deck__tile.t-ink {
  --top: oklch(34% 0.012 270); --bot: oklch(16% 0.006 270);
  --sheen: 0.08; --edge: 0.24; --ring: 0.07; --shade: 0.3;
  --acc: var(--color-accent-light); --cut: oklch(22% 0.008 270);
}
/* AI agents alone carries the colour gradients (2026-09-28): a violet glow
   in the glass and a gradient spark. Gradients are how AI is drawn now, so
   here they mean something; on the other six they would only decorate. */
.deck__tile.t-ai { --glow: oklch(66% 0.2 302 / 0.6); --glow-at: 76% 80%; --acc: url(#deck-ai); }
.deck__tile.t-white {
  --top: oklch(99.6% 0 0); --bot: oklch(94.6% 0.003 270);
  --sheen: 0; --edge: 1; --ring: 0.6; --shade: 0.07;
  --stroke: var(--color-ink); --fg: var(--color-ink); --acc: var(--color-accent); --cut: oklch(97% 0.002 270);
}
/* the glow inside the glass, under the icon */
.deck__tile::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: radial-gradient(circle at var(--glow-at), var(--glow), transparent 62%);
}
/* Behind the front, a tile is a plain sheet: a grey veil over it, darker
   one step back, lighter two back, lifting as it comes forward. */
.deck__tile::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background-color: var(--veil, var(--color-paper-3)); opacity: 1;
  transition: opacity 420ms var(--ease-out), background-color 420ms var(--ease-out);   /* slot 2 → 1 blends its shade instead of stepping */
}
.deck__tile svg {
  position: relative; z-index: 0;
  inline-size: 56%; block-size: 56%;
  fill: none; stroke: var(--stroke); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
}
.deck__tile svg .fg { fill: var(--fg); stroke: none; }
.deck__tile svg .fa { fill: var(--acc); stroke: none; }
.deck__tile svg .cut { stroke: var(--cut); stroke-width: 2.4; paint-order: stroke; }   /* a tile-coloured edge where the spark overlaps the bubble */
.deck__tile svg .sa { stroke: var(--acc); stroke-width: 3.8; }
.deck__defs { position: absolute; inline-size: 0; block-size: 0; overflow: hidden; }

.deck__tile[data-slot="0"] { transform: none; opacity: 1; z-index: 3; }
.deck__tile[data-slot="0"]::after { opacity: 0; }
.deck__tile[data-slot="0"], .deck__tile[data-slot="out"] { --veil: oklch(88.5% 0 0); }   /* slot 1's veil, held while it fades (see the hero's) */
.deck__tile[data-slot="1"] { transform: translateY(-9px) scale(0.84); opacity: 1; z-index: 2; --veil: oklch(88.5% 0 0); }   /* a step darker than the paper tokens: on the #f1f1f1 hero they barely showed */
.deck__tile[data-slot="2"] { transform: translateY(-18px) scale(0.68); opacity: 1; z-index: 1; --veil: var(--color-paper-3); }
.deck__tile[data-slot="1"], .deck__tile[data-slot="2"] { box-shadow: none; }
/* Leaving: down a touch and out, in front of the tile taking its place. */
.deck__tile[data-slot="out"] {
  transform: translateY(14px) scale(1); opacity: 0; z-index: 4;
  transition: transform 420ms var(--ease-out), opacity 300ms var(--ease-out);
}
.deck__tile[data-slot="out"]::after { opacity: 0; }

/* ============================================================ the segmented toggle
   Base style for .switch__toggle / .switch__opt. How it works and
   Redesigned both build on it through .switch--wide. It came from "What actually
   changes", the Generic/Layoutics switch removed 2026-09-22. */
.switch__toggle {
  display: inline-flex; margin-block-start: var(--space-lg);
  border: var(--rule-hair) solid var(--color-ink);
  border-radius: var(--radius-lg); overflow: hidden;
}
.switch__toggle[hidden] { display: none; }
.switch__opt {
  min-block-size: 44px; padding: 0 var(--space-md);
  border: 0; background: transparent; color: var(--color-ink);
  font: inherit; font-size: var(--text-sm); cursor: pointer;
  transition: background-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out);
}
.switch__opt:hover { background: var(--color-paper-2); }
.switch__opt[aria-pressed="true"] { background: var(--color-ink); color: var(--color-paper); }
.switch__opt:focus-visible { outline: var(--rule-bold) solid var(--color-focus); outline-offset: 2px; position: relative; }
.switch__opt:active { transform: translateY(1px); }

/* ── the wide switch (2026-09-26) ─────────────────────────────────────────────
   A choice drawn as one: the full width, two equal halves, the name in the
   display face and a mono line under it saying where it leads. Two small
   boxes on the left read as a caption and went unnoticed (owner,
   2026-09-22), and so did the case tabs at 12.8px, hence one component for
   both How it works and Redesigned. It carries the two cues everyone knows
   from forms: a prompt above (.switch__prompt) and a radio circle in each
   half, empty or filled. The chosen half is aria-pressed on a toggle group
   and aria-selected on a tablist; both are styled the same. */
.switch--wide:not([hidden]) {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  inline-size: 100%;
  border-color: var(--color-rule);
}
.switch__prompt {
  font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--color-muted);
}
.switch__prompt[hidden] { display: none; }
.switch__prompt:not([hidden]) + .switch--wide:not([hidden]) { margin-block-start: var(--space-sm); }
.switch--wide .switch__opt {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-content: center;
  column-gap: var(--space-sm); row-gap: var(--space-2xs);
  min-block-size: 4.5rem; padding: var(--space-sm) var(--space-lg);
  text-align: start; color: var(--color-muted);
}
/* The chosen half is marked, not filled (2026-09-26). A solid ink half was
   the heaviest block on the page before the proof it introduces, and the
   owner found it flashy. Now it is the ink name, the filled circle and a
   bold ink rule along its foot; the other half stays muted. */
.switch--wide .switch__opt:is([aria-pressed="true"], [aria-selected="true"]) {
  background: transparent; color: var(--color-ink);
  box-shadow: inset 0 calc(-1 * var(--rule-bold)) 0 var(--color-ink);
}
.switch--wide .switch__opt:hover { color: var(--color-ink); }
.switch__dot {
  grid-row: 1 / span 2; align-self: center;
  inline-size: 1.25rem; block-size: 1.25rem; border-radius: 50%;
  border: 1.5px solid currentColor;
  position: relative;
}
.switch__dot::after {
  content: ""; position: absolute; inset: 3px; border-radius: 50%;
  background: currentColor; transform: scale(0);
  transition: transform var(--dur-short) var(--ease-out);
}
.switch--wide .switch__opt:is([aria-pressed="true"], [aria-selected="true"]) .switch__dot::after { transform: scale(1); }
.switch--wide .switch__opt:hover .switch__dot { border-color: var(--color-accent); }
.switch--wide .switch__opt + .switch__opt { border-inline-start: var(--rule-hair) solid var(--color-rule); }
.switch__name {
  font-family: var(--font-display); font-variation-settings: "opsz" 36, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: var(--text-lg); line-height: 1.1; letter-spacing: var(--track-sm);
}
.switch__sub {
  font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--color-muted);
}
/* Phones keep the two halves side by side (owner, 2026-09-28): a stacked pair
   read as a list, not a choice. Each half is ~150px, so the circle sits
   beside the name only and the sub runs the full half below, free to wrap. */
@media (max-width: 40rem) {
  .switch--wide .switch__opt {
    min-block-size: 4rem; padding: var(--space-sm) var(--space-sm);
    align-content: start; column-gap: var(--space-2xs);
  }
  .switch--wide .switch__dot { grid-row: 1; inline-size: 1rem; block-size: 1rem; }
  .switch--wide .switch__dot::after { inset: 2.5px; }
  .switch__name { font-size: var(--text-md); white-space: nowrap; }   /* one line down to 320 */
  .switch__sub { grid-column: 1 / -1; letter-spacing: 0.06em; line-height: 1.4; }
  .switch__to { display: block; }   /* both halves break after the arrow: two matching lines (owner, 2026-09-28) */
}
@media (max-width: 22.5rem) { .switch__name { font-size: var(--text-base); } }   /* "Ayah Kutub" fits a 320 half */

/* ============================================================ the featured build
 * Input → arrow → output, with a spec beside it. A before/after frame needs a
 * before; this case never had one, so the input is the brief instead.
 */

.build { margin-block-start: var(--space-lg); }
.build__name {
  font-size: var(--text-xl);
  --opsz: 48;
  --track: var(--track-md);
  margin-block-start: var(--space-xl);
}
/* THE TAIL OF #build, AND WHY THERE ISN'T ONE (2026-09-21, three passes).
   It started as four definition rows — Hard part / Refused / Built /
   Centrepiece — whose value column ran to 116ch, nearly 2x the --measure token
   the rest of the page obeys, each one a single-line ribbon. 94 words, 448px,
   25% of the section, all of it AFTER the reader has watched the site load.
   Pass 1 capped the measure and lifted Refused out as a display statement.
   That made it clearer and TALLER — 246 -> 448px — which fixed the typography
   and not the problem.
   Pass 2 cut Hard part, Built and Centrepiece. Hard part was about the
   client's business, Built named typefaces for designers, and Centrepiece
   described an interaction the reader could go and have. The centrepiece
   became the link: "Open the live site" -> "Watch it build ->", the same
   payload in 3 words instead of 24.
   Pass 3 cut Refused too, and the reason is the one worth keeping. The case
   for it was that it answered the "A modern, minimal website." quote opening
   the section, and was the only place the page stated a design position.
   Measured, both are false: the quote is 1280px above it, which is not a
   callback, and "AI isn't the problem. Generic thinking is." lands 523px BELOW
   it — the same point, larger, in a section built to make it. Refused was a
   weaker preview of the section that follows it. That is why it read as
   pointless with the rows gone: nothing was holding it up.
   So #build now ends on the caption and one door. It states no conclusion,
   because it does not need one — the brief goes in as six words, the site
   comes out live in three states, and the reader draws it. That is the page's
   own principle (perform the claim, don't describe it) applied to the section
   that was describing hardest.
   94 -> 3 words. Tail 448 -> 44px. Section 1787 -> ~1340.
   DO NOT re-add a text block here. Four visual replacements were considered
   across the three passes and all are on the rejected list: generic-vs-ours
   specimens (the spec sheet owns that device), the fit-out sequence (built,
   shipped, pulled), live specimens of Instrument Serif and Schibsted Grotesk
   (two webfonts to show what the frame already shows), and a stat band. And
   a visual here would still be making a point the NEXT SECTION makes better.
   The slot is redundant, not under-designed. */
.build__actions { margin-block-start: var(--space-md); }

/* The whole written starting point, said once. It used to be two rows — CAME
   WITH and ASKED FOR — at the top of a four-row table, which is what put 591px
   of prose between the heading and the first thing worth looking at. */
.build__ask {
  margin-block-start: var(--space-lg);
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: var(--space-sm) var(--space-md);
}
.build__quote {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 36, "SOFT" 0, "WONK" 0;
  font-weight: 600;
  font-size: var(--text-lg);
  letter-spacing: var(--track-sm);
}
.build__kicker {
  font-family: var(--font-mono); font-size: var(--text-xs);
  letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted);
}

.build__arrow {
  margin-block: var(--space-lg) 0;
  font-size: var(--text-lg);
  color: var(--color-accent);
  line-height: 1;
}
/* The contact sheet (their folder of photography, as a strip of
   thumbnails) was removed on 2026-09-22. The story is input → output, and the
   one-line brief is the strongest input. The photographs appear anyway,
   larger, inside the live site below. See the header note. */

.build__figure { margin: var(--space-lg) 0 0; min-width: 0; }

/* Everything that annotates the centre frame aligns TO the centre frame.
   The triptych is full-bleed with a minmax(0, 62vw) centre column, so the frame
   starts at 19vw while the shell starts wherever the shell starts. At 1440 that
   left the label, the caption and the link at x=120 describing a frame at
   x=274 — 154px adrift, sitting under the Arabic side panel rather than under
   the thing they refer to. The scroll hint was already frame-aligned (it is
   absolute inside .build__stage), so the label band did not even bracket the
   same box: label at the shell edge, hint on the frame's right edge.
   calc((100% - 62vw) / 2) is the frame's left edge expressed against the shell.
   It keeps working past the shell cap, where the term goes negative and follows
   the bleed the same way the triptych does.
   The caption also carried max-width:none and ran to 130ch — the last uncapped
   measure left in the section after the spec rows went. */
.build__figure .dip__label--after,
.build__actions,
.build__arrow {   /* the arrow too (2026-09-29): at the shell edge it pointed at the Arabic side panel, not the site the brief became */
  margin-inline-start: calc((100% - 62vw) / 2);
}

/* ---- the triptych ----------------------------------------------------
   Two moves, both taken from Squarespace's carousel and neither of them its
   styling. First: the centre panel is ~62% of the VIEWPORT, not the full
   shell. Full width read as huge — a 1168x657 slab — and 62% brings it to
   about 860x484 without making it a thumbnail.

   Second: Squarespace fills its margins with the NEXT PANELS OF ITS OWN
   PRODUCT, so the centre reads as one of a series. The sides here are the same
   build at its other two states — Arabic with real RTL, and at a narrow width.
   All three panels are our work, and the margins say "there is more of this
   site" rather than anything the reader has to decode.

   REJECTED in this slot, and worth not repeating: the fit-out sequence —
   stage 01 (bare concrete shell) on the left, stage 15 (finished restaurant)
   on the right, with the site between them. It looked strong and it was wrong
   on three counts. The transformation on display is EURODECOR'S, not ours —
   the most dramatic object in a section about our work was a room we did not
   build. It is a category error: the section is about building a WEBSITE from
   scratch and the pictures are about building a ROOM, so the reader has to
   make the leap shell:restaurant :: brief:website. And the caption had to
   explain it ("the same room, the same camera, fifteen stages apart"), which
   is the tell — a visual that needs a sentence to decode carries less than the
   sentence. There was also a real risk a visitor concluded Layoutics does
   fit-out.

   The sides bleed off the viewport on purpose. Contained, they would read as
   two more pictures that happen to be there; running off the edge they read as
   a set continuing past the frame.

   On the two captures, because they are not obvious. ARABIC is the right 40% of
   a 1440 desktop shot — in RTL the logo, the nav and the headline all live on
   that side, so a portrait slice still reads as the page. NARROW is a 768px
   capture cropped x 0-1040, y 590-2521. Three things that crop must get right,
   each learned by getting it wrong first:
     · START AT x=0, not at the text. The site's own 78px left padding IS the
       gutter. Cropping to the text put it flush against the panel edge and
       shaved the first letter off every line of body copy.
     · MEASURE THE WIDEST RUN, not the headline. The eyebrow reaches x=1080 and
       the body 993; the headline only 897. A crop sized to the headline clips
       the paragraph. Only the eyebrow's tail is allowed to bleed.
     · CENTRE ON THE CONTENT, not the capture. Their hero is 100vh, so its
       airiness follows the capture height — taking the full frame dumped a
       third of the panel as dead space above the text and halved the type.
   The nav is the casualty at this aspect; the centre panel's full nav beside
   it already carries that contrast.
   Narrow is captured at 768, NOT at phone width: headless renders their
   desktop text metrics at phone widths whatever user-agent you send (GSAP
   SplitText measures before layout settles) and the headline overflows its
   container. The live site is fine at 375 — verified in a real browser. Do not
   ship a phone capture from headless; it libels our own build. */
.triptych {
  margin-block-start: var(--space-sm);
  /* Measured, not assumed: this centres exactly and the two 1fr sides come out
     identical (250/250, gaps 24/24, stage centre offset 0) with or without a
     classic scrollbar. A --sbw correction was tried here and reverted — it
     changed nothing visible and put a JS dependency under a CSS layout. */
  margin-inline: calc(50% - 50vw);
  inline-size: 100vw;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 62vw) minmax(0, 1fr);
  gap: var(--space-lg);
  align-items: stretch;
}
.triptych__side {
  position: relative; overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--color-paper-2);
}
.triptych__side img { inline-size: 100%; block-size: 100%; object-fit: cover; }
/* Where the sides bleed off the screen (above 60rem), only the corners facing
   the frame are rounded: a curve on an edge the screen cuts off reads as a
   mistake (owner, 2026-09-28). Logical corners, so it mirrors in Arabic. Below
   60rem they sit inside the page and keep all four. */
@media (min-width: 60.0625rem) {
  .triptych__side--a { border-start-start-radius: 0; border-end-start-radius: 0; }
  .triptych__side--b { border-start-end-radius: 0; border-end-end-radius: 0; }
}
/* each side leans toward the centre, so both halves of the room face the site */
.triptych__side--a img { object-position: 70% 50%; }
.triptych__side--b img { object-position: 30% 50%; }
.triptych__tag {
  position: absolute;
  inset-block-end: var(--space-sm); inset-inline-start: var(--space-sm);
  padding: 0.25rem 0.5rem;
  background: var(--color-ink); color: var(--color-paper);
  font-family: var(--font-mono); font-size: var(--text-xs);
  letter-spacing: 0.03em; text-transform: uppercase;
  border-radius: var(--radius-xs);
}
.triptych .build__stage { min-inline-size: 0; }
.build__doc { position: absolute; inset-block-start: 0; inset-inline-start: 0; border: 0; transform-origin: top left; }
/* Two classes on purpose. `.dip__frame` sets 7/6 further down the file, and at
   equal specificity the later rule wins — a bare `.build__frame` here is
   silently overridden and the frame renders 1001px tall. The diptych's 7/6 is
   argued for a 592px scroll-synced pane; a single full-width frame is a window
   onto a desktop screen and should be shaped like one. */
.build__figure .build__frame { aspect-ratio: 16 / 9; background: #0c0c0d; }   /* EuroDecor's black while it loads, not an empty grey box (2026-10-01) */

/* frame-scroll affordance. The framed site scrolls INDEPENDENTLY of the page,
   which is not an expectation anyone arrives with, and the payoff behind it —
   the fifteen-stage build sequence — is the best thing in this case. It replaces
   two weak cues: an arrow above the frame, and an instruction in the caption
   BELOW it, i.e. arriving after you had already scrolled past.
   It sits in the GUTTER, not on the artwork. Every other annotation on this page
   is a mono label outside the thing it describes — the URL above the frame, the
   spec keys beside their values — so laying this one over the content broke the
   grammar. It also meant printing our own chrome across a client's hero, which
   is a poor argument from a studio selling respect for craft.
   Wording is "inside", never a bare "Scroll": the page scrolls too, and the
   ambiguity would push the visitor toward exactly the wrong gesture.
   It LEAVES on engagement. The frame is cross-origin, so its scroll offset is
   unreadable; pointer-enter is the proxy. A prompt that survives being obeyed is
   clutter — the flaw in the reference implementation.
   Desktop only. The gate used to be load-bearing because .build__grid collapsed
   at 48rem; the frame is full width now and .build__stage carries its own hint
   track, so the 48.0625rem floor is simply "wide enough for a vertical label
   beside the frame". Touch is excluded on purpose: scrolling inside an iframe fights
   the page scroll. Phone and keyboard visitors get the "Open the live site"
   link instead, the latter because the iframe is deliberately tabindex="-1". */
/* The hint's old gutter was the empty half of the 7/5 grid. With the frame at
   full width the stage becomes a two-track grid instead, so the affordance
   still sits BESIDE the artwork and never on it. */
/* ONE track, not two. A second track for the hint made the stage 32px wider
   than the frame inside it, so the grid column was even while the VISIBLE
   panel was not: 24px of gap on its left and 56px on its right. The hint is
   positioned out of flow instead — see the chip below. */
.build__stage { position: relative; }
.framehint { display: none; }

@media (min-width: 48.0625rem) and (pointer: fine) {
  /* A CHIP on the frame, not a label in a gutter. The original sat in the empty
     half of a 7/5 grid — "beside the artwork, never on it". The triptych filled
     that gutter with the other two states of the site, so there is no longer a
     beside to sit in, and reserving one distorted the centre panel. The side
     panels already carry mono chips ON the image (ARABIC · RTL, NARROW); this
     matches them, so the three panels now label themselves the same way.
     2026-09-21 — the chip came OFF the centre panel, and the paragraph above
     is kept only as the record of why it was ever on it. Matching the side
     panels was the wrong goal: those are static screenshots with dead corners,
     and the centre is a LIVE SITE that fills all four of its own. END overlapped
     EuroDecor's "View our work" / "Let's talk" by ~100px and, being another dark
     pill, read as a third button of theirs; START then covered the last line of
     their body copy. There is no free corner to move to, and there will not be
     one — their hero is not ours to arrange. So the hint now sits on OUR paper,
     in the label band directly above the frame, right-aligned to its edge and
     opposite EURODECORKSA.COM · LIVE. It reads before you enter the frame, which
     is when a scroll affordance is actually useful. The dark pill is gone with
     it: on paper this is a mono annotation like every other label on the page.
     Do not put it back inside the frame. */
  .framehint {
    position: absolute;
    inset-block-end: calc(100% + var(--space-2xs));
    inset-inline-end: 0;
    margin: 0;
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    padding: 0;
    pointer-events: none;
    opacity: 0;                        /* held back until the frame has painted */
    transition: opacity var(--dur-long) var(--ease-out),
                transform var(--dur-long) var(--ease-out);
  }
  .build__frame[data-loaded="true"] + .framehint { opacity: 1; }
  .framehint__rule {
    inline-size: 0.75rem;
    block-size: var(--rule-bold);
    background: var(--color-accent);
  }
  .framehint__text {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--color-muted);     /* on paper now, not on the dark frame */
    white-space: nowrap;
  }
  .build__frame[data-loaded="true"] + .framehint[data-done="true"] {
    opacity: 0;
    transform: translateY(0.5rem);
  }
}

/* ============================================================ case study */

.case__meta {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-muted);
  padding-block-start: var(--space-md);
  border-block-start: var(--rule-hair) solid var(--color-rule);
  line-height: 1.7;
}

/* ---- the diptych: two live sites, scrolled in step ----
 * Both are same-origin local copies, so their scroll position can be driven
 * from here. A cross-origin (mode: "url") case degrades to a static frame
 * plus the live link — stated in the hint rather than failing silently.
 */

.dip { margin-block-start: var(--space-2xl); }

/* Tabs are <button>s, not the CSS-only radio pattern — radios at
   position:absolute make the page jump to the section top on every click
   (slop-test gate 53). They are drawn as the wide switch (2026-09-26): as
   12.8px grey words with an underline they read as page navigation, not as
   "pick a case". */
.dip__tabs { margin-block-end: var(--space-lg); }

.dip__sector {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: 0.03em;
  color: var(--color-muted);
  margin-block-end: var(--space-md);
}
/* A case whose "after" is framed live is cross-origin: its scroll cannot be
   driven from this page, so the shared scrubber is withdrawn rather than left
   looking broken, and the hint says why. */
.dip[data-sync="false"] .dip__scrub { display: none; }
.dip[data-sync="false"] .dip__doc { pointer-events: auto; }
/* Our own copies take no clicks (2026-10-10 security check, owner chose it):
   the scrubber moves them, and a click inside could reach a client copy's
   contact form, which sends real enquiries to the client (BizArch's goes to
   their live form service). As EuroDecor's (.build__doc). A live, cross-origin
   case keeps its pointer (the rule above): there the visitor scrolls it. */
.dip:not([data-sync="false"]) .dip__doc { pointer-events: none; }
.dip__frame[data-state="pending"]::after {
  content: attr(data-message);
  position: absolute; inset: 0;
  display: grid; place-items: center;
  padding: var(--space-lg);
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--color-muted);
  background: var(--color-paper-2);
}
.dip__pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-md);
}
.dip__half { margin: 0; min-width: 0; }
/* The other case, beside the panels (2026-09-27). In the page margin, so only
   where the margin can hold a 40px button: the gutter is 5vw, 56px at 70rem. */
.dip__pair { position: relative; }
.dip__arrow {
  display: none; place-items: center;
  position: absolute; top: 50%; translate: 0 -50%;
  inline-size: 40px; block-size: 40px; padding: 0;
  border: var(--rule-hair) solid var(--color-ink-2); border-radius: var(--radius-md);
  background: var(--color-paper); color: var(--color-ink); cursor: pointer;
  transition: background-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out);
}
.dip__arrow svg { inline-size: 18px; block-size: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: square; }
.dip__arrow:hover { background: var(--color-ink); color: var(--color-paper); }
.dip__arrow:focus-visible { outline: var(--rule-bold) solid var(--color-focus); outline-offset: 3px; }
.dip__arrow--prev { right: calc(100% + var(--space-xs)); }
.dip__arrow--next { left: calc(100% + var(--space-xs)); }
@media (min-width: 70rem) { .dip__arrow:not([hidden]) { display: grid; } }
.dip__label {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-muted);
  padding-block-end: var(--space-xs);
}
.dip__label--after { color: var(--color-ink); }
.dip__label--after::before {
  content: "";
  display: inline-block; inline-size: 6px; block-size: 6px;
  margin-inline-end: 0.5rem; vertical-align: 0.1em;
  background: var(--color-accent);
}
/* The pair's labels (2026-09-28): a chip on BOTH sides, then what each side
   is, in readable sentence case. Before is a quiet grey chip, After the solid
   blue one. Above the frame, never on it: our annotation never goes inside a
   client's frame. The EuroDecor caption stays the quiet square style: one
   site has nothing to tell apart, and a chip there stopped the brief → ↓ → site
   flow (tried and reverted 2026-09-28). */
.dip__label--pair {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-xs) var(--space-sm);
  padding-block-end: var(--space-sm);
  font-family: var(--font-body); font-size: var(--text-base); letter-spacing: 0; text-transform: none;
  color: var(--color-ink);
}
.dip__label--pair::before { content: none; }
.dip__chip {
  display: inline-flex; align-items: center;
  --ls: 0.03em;   /* end padding short by one letter-space: tracking trails the last letter */
  padding: 0.45em calc(0.8em - var(--ls)) 0.45em 0.8em; border-radius: var(--radius-sm);
  font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 500;
  letter-spacing: var(--ls); text-transform: uppercase; line-height: 1;
}
.dip__chip--before { background: var(--color-ink); color: var(--color-paper); }   /* a grey chip vanished on the grey page (owner) */
.dip__chip--after  { background: var(--color-accent); color: var(--color-accent-ink); }
.dip__what { font-weight: 500; }
.dip__frame {
  position: relative;
  overflow: hidden;
  /* Locked, because it used to be a block-size clamp and the ratio was never
     chosen — it fell out of whatever the clamp produced against the grid,
     drifting 1.05 at 1024px to 1.16 at 1920px, so the frame changed shape as
     you resized. 4/3 rather than a true 16/10 viewport: these panels are
     scroll-synced, which makes the frame a window you travel THROUGH, not a
     simulation of someone's browser, and for that job seeing more page per
     position wins over viewport fidelity. 7/6 specifically: at 592px wide it
     restores the ~1248px window the old clamp produced at desktop widths, so
     locking the shape costs no visible page — the earlier 16/10 and 4/3 both
     paid 13-28% of it for fidelity this frame does not owe anyone. Mobile
     takes the true 16/10 instead: no sync there, so one static frame has to
     read as a desktop screen on its own. */
  aspect-ratio: 7 / 6;
  border: var(--rule-hair) solid var(--color-rule);
  background: var(--color-paper-2);
  border-radius: var(--radius-lg);
  /* clip-path, not just overflow: iOS Safari does not clip transformed
     children (the scaled frames, the moving stills) to a border-radius */
  clip-path: inset(0 round var(--radius-lg));
}
.dip__doc {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  border: 0;
  transform-origin: top left;
  /* width / height / scale are set from JS once the panel is measured */
}
/* On touch the panel holds a still instead (app.js, freshShot): the page's
   tiles stacked at the panel's width, moved up by apply(). */
.dip__shot { inline-size: 100%; }
.dip__shot img { display: block; inline-size: 100%; block-size: auto; }
.dip__frame[data-ready="false"]::after {
  content: "Loading the live site…";
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-muted);
  background: var(--color-paper-2);
}

.dip__controls { margin-block-start: var(--space-md); }
.dip__scrub {
  inline-size: 100%;
  block-size: 44px;
  margin: 0;
  cursor: ew-resize;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
}
.dip__scrub::-webkit-slider-runnable-track {
  block-size: var(--rule-bold);
  background: var(--color-rule);
}
.dip__scrub::-moz-range-track { block-size: var(--rule-bold); background: var(--color-rule); }
.dip__scrub::-webkit-slider-thumb {
  -webkit-appearance: none;
  inline-size: 18px; block-size: 18px;
  margin-block-start: -8px;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
  border: 0;
}
.dip__scrub::-moz-range-thumb {
  inline-size: 18px; block-size: 18px;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
  border: 0;
}
.dip__scrub:focus { outline: none; }
.dip__scrub:focus-visible { outline: var(--rule-bold) solid var(--color-focus); outline-offset: 4px; }

.dip__hint {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs) var(--space-lg);
  margin-block-start: var(--space-2xs);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* "2 cases · Next: Ayah Kutub →", pushed to the end of the hint row: where the
   eye lands when the panels finish, and the only place with room on a phone. */
.dip__other { display: inline-flex; align-items: center; gap: var(--space-sm); margin-inline-start: auto; }
.dip__count { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.dip__next { padding: 0; border: 0; background: none; font: inherit; font-weight: 600; color: var(--color-ink); cursor: pointer; }
/* the end-of-run cue (JS adds .is-cued once per visit): the arrow fills once and
   the link's underline turns to the accent, then both settle back */
.dip.is-cued .dip__arrow:not([hidden]) { animation: dip-cue 1.6s var(--ease-out); }
.dip.is-cued .dip__next { text-decoration-color: var(--color-accent); text-decoration-thickness: 2px; }
@keyframes dip-cue {
  0%, 100% { background: var(--color-paper); color: var(--color-ink); }
  25%, 60% { background: var(--color-ink); color: var(--color-paper); }
}

/* ============================================================ more than a website (the capability carousel)
   On the concept of Squarespace's "Grow your business", studied live
   2026-09-21: one headline, one line, a row of tabs, and a carousel of large
   16:10 cards (theirs 893×558 at 1440 — ours the same proportion) with the
   neighbours peeking in, advancing about every five seconds, with a pause.
   OUR version, not a clone: our type, square corners, an ink underline where
   they use a grey pill, and no stock photography — Squarespace sets each demo
   on a photograph; ours are drawn compositions (an interface and one or two
   floating panels) in the page's own tokens, on a night surface with a glow.
   Every brand drawn here is an invented SAMPLE and is tagged as one.
   Without JS the track is a native scroll-snap carousel you can swipe or
   scroll; JS adds tabs, the pause, the dots and the advance. */
.more__head { display: flex; flex-direction: column; align-items: center; gap: var(--space-sm); text-align: center; }
.more__sub { color: var(--color-ink-2); font-size: var(--text-md); line-height: 1.4; text-wrap: balance; }   /* body 1.6 left a gap between its two phone lines wider than the heading's (2026-09-28) */

.more { --card-w: min(56rem, 84vw); margin-block-start: var(--space-xl); }

/* one row, always: when the six tabs don't fit it scrolls sideways, as
   Squarespace's strip does, and the script keeps the active tab in view.
   "safe center" centres the row only while it fits, so the first tab is
   never pushed off the start. */
.more__tabs {
  position: relative;
  display: flex; justify-content: safe center; gap: var(--space-2xs);   /* the pills carry their own padding */
  margin-block-end: calc(var(--space-xl) - 18px);
  overflow-x: auto; scrollbar-width: none;
  padding: 10px var(--space-2xs) 18px;              /* room for the pill's shadow: overflow-x clips vertically too */
  margin-block-start: -10px;
}
.more__tabs::-webkit-scrollbar { display: none; }
.more__tabs[hidden] { display: none; }
.more__tab {
  position: relative; z-index: 1;   /* above the sliding pill */
  flex: none; white-space: nowrap;
  min-block-size: 44px; padding: 0 1.1rem; border-radius: 999px;
  border: 0; background: none; cursor: pointer;
  font: inherit; font-size: var(--text-base); color: var(--color-muted);
  transition: color var(--dur-short) var(--ease-out);
}
.more__tab:hover, .more__tab[aria-selected="true"] { color: var(--color-ink); }
.more__tab:focus-visible { outline: var(--rule-bold) solid var(--color-focus); outline-offset: -2px; }
/* The sliding pill (2026-09-28, was an ink underline). Squarespace slides a
   grey pill on white; on our grey a grey pill vanishes, so this is the nav's
   raised white pill, the page's one "you are here" mark. */
.more__ink {
  position: absolute; inset-block-start: 0; inset-inline-start: 0;
  inline-size: var(--w, 0); block-size: var(--h, 0);
  background: var(--color-card); border-radius: 999px;
  box-shadow: 0 0 0 var(--rule-hair) var(--color-rule-2), 0 4px 14px oklch(20% 0.005 270 / 0.07), 0 1px 2px oklch(20% 0.005 270 / 0.05);
  transform: translate(var(--x, 0), var(--y, 0));   /* y too, in case the row ever wraps */
  transition: transform 0.45s var(--ease-out), inline-size 0.45s var(--ease-out);
  pointer-events: none;
}

/* full-bleed native scroller: the padding lets the first and last cards centre */
.more__viewport {
  position: relative;
  margin-inline: calc(50% - 50vw); inline-size: 100vw;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.more__viewport::-webkit-scrollbar { display: none; }
.more__viewport:focus-visible { outline: var(--rule-bold) solid var(--color-focus); outline-offset: -4px; }
.more__track {
  list-style: none; margin: 0;
  display: flex; gap: clamp(var(--space-md), 2.8vw, var(--space-xl));
  padding: 0 calc(50vw - var(--card-w) / 2);
  inline-size: max-content;
}

.mcard {
  --glow-x: 80%; --glow-y: 15%;
  position: relative; flex: 0 0 var(--card-w);
  aspect-ratio: 16 / 10;
  container-type: inline-size;
  scroll-snap-align: center;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background:
    radial-gradient(ellipse 55% 70% at var(--glow-x) var(--glow-y), var(--color-glow-night), transparent 70%),
    linear-gradient(160deg, var(--color-night-paper-3), var(--color-night-paper) 60%);
  color: var(--color-night-ink);
}
#more-services  { --glow-x: 15%; --glow-y: 85%; }
#more-bookings  { --glow-x: 20%; --glow-y: 90%; }
#more-platforms { --glow-x: 85%; --glow-y: 20%; }
#more-invoicing { --glow-x: 85%; --glow-y: 85%; }
#more-apps      { --glow-x: 55%; --glow-y: 10%; }
/* a stable layer per card, at every width (phones had it since 2026-09-29;
   desktop Safari since 2026-10-08, owner's brother's MacBook): the cards are
   drawn with blurs, blends and clipped corners inside a moving track, and
   without their own layer Safari re-rasterised them unevenly, blanking the
   card arriving in the middle and, now and then, a peek while the page
   scrolled. Chrome looks the same either way. */
.mcard { transform: translateZ(0); isolation: isolate; }
.more.is-live .mcard:not(.is-active) { cursor: pointer; }

.mcard__text {
  position: absolute; z-index: 2;
  inset-block-start: 7%; inset-inline-start: 5.5%;
  max-inline-size: min(44%, calc(24rem * var(--card-z, 1)));
  display: flex; flex-direction: column; gap: calc(var(--space-xs) * var(--card-z, 1));
}
.mcard__title {
  font-size: calc(clamp(var(--text-lg), 2.4vw, var(--text-xl)) * var(--card-z, 1));   /* --card-z: app.js, short windows only */
  --opsz: 36; --track: var(--track-md); --leading: 1.05;
  color: var(--color-night-ink);
}
.mcard__p { font-size: calc(var(--text-sm) * var(--card-z, 1)); line-height: 1.5; color: var(--color-night-ink-2); }
.mcard__for { font-size: calc(var(--text-xs) * var(--card-z, 1)); color: var(--color-night-ink-2); letter-spacing: 0.01em; }
.mcard__for span { font-family: var(--font-mono); letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-night-muted); }

/* ---- the drawings: everything in cqi off the card, so each composition
   scales as one object. i / b / em / u are drawing primitives (aria-hidden). */
.mcard__art { position: absolute; inset: 0; }
:where(.mcard__art) :is(i, b, em, u) {
  display: block; font-style: normal; font-weight: inherit; text-decoration: none;
}
:where(.mcard__art) span { display: block; }   /* zero-specificity default, so each part sets its own display */

/* a site window — no fake browser chrome, just the page's own top bar */
.mk {
  position: absolute; inset-inline-end: 5cqi; inset-block-end: -5cqi;
  inline-size: 57cqi;
  padding: 2.2cqi 2.6cqi;
  background: var(--color-paper); color: var(--color-ink);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-float);
}
.mk__bar { display: flex; align-items: center; gap: 2cqi; padding-block-end: 1.6cqi; border-block-end: var(--rule-hair) solid var(--color-rule); }
.mk__brand {
  font-family: var(--font-display); font-variation-settings: "opsz" 24, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: 1.55cqi; letter-spacing: var(--track-sm); white-space: nowrap;
}
.mk__nav { display: flex; gap: 1.4cqi; margin-inline-start: auto; }
.mk__nav i { inline-size: 3.6cqi; block-size: 0.35cqi; background: var(--color-rule); }
.mk__pill { padding: 0.5cqi 1.4cqi; background: var(--color-ink); color: var(--color-paper); font-size: 0.95cqi; font-family: var(--font-body); border-radius: var(--radius-xs); }
.mk__kicker { font-family: var(--font-mono); font-size: 0.85cqi; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.mk__h {
  font-family: var(--font-display); font-variation-settings: "opsz" 36, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: 2.6cqi; line-height: 1.05; letter-spacing: var(--track-md);
}
.mk__lines { display: flex; flex-direction: column; gap: 0.7cqi; }
.mk__lines i { block-size: 0.4cqi; background: var(--color-rule); }
.mk__lines i + i { inline-size: 70%; }
.mk__btn {
  align-self: flex-start; padding: 0.9cqi 2cqi;
  background: var(--color-ink); color: var(--color-paper);
  font-family: var(--font-body); font-size: 1.05cqi; font-weight: 600; border-radius: var(--radius-xs);
}
.mk__shot { background: linear-gradient(170deg, var(--color-paper-2), var(--color-paper-3)); border-radius: var(--radius-xs); position: relative; overflow: hidden; }

/* 1 · store — the product, drawn: a coffee bag, not a stock photo */
.mk__store { display: grid; grid-template-columns: 1fr 1fr; gap: 2.6cqi; padding-block: 2.2cqi; }
.mk__shot--bag { aspect-ratio: 5 / 4; display: grid; place-items: center; }
.bag {
  inline-size: 44%; aspect-ratio: 0.72;
  background: linear-gradient(100deg, var(--color-ink-2), var(--color-ink) 55%, var(--color-ink-2));
  border-radius: 0.8cqi 0.8cqi 0.4cqi 0.4cqi;
  display: grid; place-items: center;
  box-shadow: 0 1.2cqi 2cqi -0.8cqi oklch(17% 0.012 45 / 0.5);
  position: relative;
}
.bag::before { content: ""; position: absolute; inset-inline: 0; inset-block-start: 7%; block-size: 0.3cqi; background: oklch(96.5% 0.006 60 / 0.25); }
.bag__label {
  inline-size: 74%; padding: 1cqi 0.6cqi; text-align: center;
  background: var(--color-paper); color: var(--color-ink);
  font-family: var(--font-display); font-variation-settings: "opsz" 24, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: 1cqi; line-height: 1.15;
}
.mk__pdp { display: flex; flex-direction: column; justify-content: center; gap: 1.3cqi; }
.mk__opts { display: flex; gap: 0.8cqi; }
.mk__opts em { padding: 0.5cqi 1cqi; border: var(--rule-hair) solid var(--color-rule); font-size: 0.95cqi; font-family: var(--font-body); border-radius: var(--radius-xs); }
.mk__opts em.is-on { border-color: var(--color-ink); box-shadow: inset 0 0 0 1px var(--color-ink); }
.mk__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.4cqi; }
.mk__grid i { aspect-ratio: 1; background: linear-gradient(170deg, var(--color-paper-2), var(--color-paper-3)); border-radius: var(--radius-xs); }

/* floating panels */
.fl {
  position: absolute; z-index: 1;
  padding: 1.8cqi;
  background: var(--color-paper); color: var(--color-ink);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-float);
  font-size: 1.05cqi;
  transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out);
}
.more.is-live .mcard:not(.is-active) .fl { opacity: 0; transform: translateY(2.5cqi); }
.more.is-live .mcard.is-active .fl--chip, .more.is-live .mcard.is-active .fl--push, .more.is-live .mcard.is-active .fl--pay { transition-delay: 0.15s; }
.fl__k { font-family: var(--font-mono); font-size: 0.85cqi; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); margin-block-end: 1.2cqi; }
.fl__cta {
  margin-block-start: 1.4cqi; padding: 1cqi; text-align: center;
  background: var(--color-accent); color: var(--color-accent-ink);
  font-family: var(--font-body); font-weight: 600; font-size: 1.05cqi; border-radius: var(--radius-xs);
}

.fl--cart { inset-inline-start: 31cqi; inset-block-end: 6cqi; inline-size: 22cqi; }
.fl__row { display: grid; grid-template-columns: 3cqi 1fr auto; align-items: center; gap: 1cqi; padding-block: 0.8cqi; border-block-end: var(--rule-hair) solid var(--color-rule-2); }
.fl__thumb { inline-size: 3cqi; aspect-ratio: 1; background: var(--color-ink); border-radius: var(--radius-xs); }
.fl__thumb--2 { background: var(--color-paper-3); }
.fl__q { color: var(--color-muted); }
.fl__opt { display: flex; align-items: center; gap: 0.8cqi; margin-block-start: 1.2cqi; color: var(--color-ink-2); }
.fl__radio { flex: none; inline-size: 1.2cqi; aspect-ratio: 1; border-radius: 50%; border: var(--rule-hair) solid var(--color-ink); position: relative; }
.fl__radio.is-on::after { content: ""; position: absolute; inset: 25%; border-radius: 50%; background: var(--color-ink); }

/* 2 · bookings */
/* picture left, treatments right: the floating slot picker overlaps the
   picture, never the list that explains the page */
.mk__spa { display: grid; grid-template-columns: 1fr 1.15fr; gap: 2.6cqi; padding-block: 2.4cqi 3cqi; }
.mk__spa .mk__shot--stone { order: -1; }
.mk__svc { display: flex; flex-direction: column; gap: 0.2cqi; }
.mk__svc .mk__h { margin-block-end: 1.2cqi; }
.svc { display: flex; justify-content: space-between; align-items: baseline; padding-block: 1cqi; border-block-end: var(--rule-hair) solid var(--color-rule); font-size: 1.1cqi; }
.svc em { font-family: var(--font-mono); font-size: 0.85cqi; color: var(--color-muted); }
.mk__shot--stone { min-block-size: 22cqi; display: grid; place-items: end center; padding-block-end: 3cqi; }
.stones { display: flex; flex-direction: column; align-items: center; }
.stones i { background: linear-gradient(180deg, var(--color-neutral), var(--color-muted)); border-radius: 50%; box-shadow: 0 0.4cqi 0.6cqi -0.2cqi oklch(17% 0.012 45 / 0.4); }
.stones i:nth-child(1) { inline-size: 5cqi; block-size: 2cqi; }
.stones i:nth-child(2) { inline-size: 7.5cqi; block-size: 2.6cqi; margin-block-start: -0.3cqi; }
.stones i:nth-child(3) { inline-size: 10cqi; block-size: 3.2cqi; margin-block-start: -0.3cqi; }

.fl--slots { inset-inline-start: 29cqi; inset-block-end: 5cqi; inline-size: 25cqi; }
.fl__days { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0.6cqi; }
.fl__days em { display: flex; flex-direction: column; align-items: center; gap: 0.3cqi; padding-block: 0.8cqi; border-radius: var(--radius-xs); font-size: 0.85cqi; color: var(--color-muted); font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.03em; }
.fl__days em b { display: block; font-family: var(--font-body); font-size: 1.4cqi; font-weight: 600; color: var(--color-ink); letter-spacing: 0; }
.fl__days em.is-on { background: var(--color-ink); color: var(--color-night-ink-2); }
.fl__days em.is-on b { color: var(--color-paper); }
.fl__times { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.6cqi; margin-block-start: 1.2cqi; }
.fl__times em { padding-block: 0.8cqi; text-align: center; border: var(--rule-hair) solid var(--color-rule); border-radius: var(--radius-xs); font-size: 1cqi; font-family: var(--font-body); }
.fl__times em.is-on { border-color: var(--color-ink); box-shadow: inset 0 0 0 1px var(--color-ink); font-weight: 600; }
.fl--chip {
  inset-inline-end: 3cqi; inset-block-start: 17cqi;
  display: flex; align-items: center; gap: 0.9cqi;
  padding: 1cqi 1.6cqi; font-size: 1.05cqi; font-weight: 600;
}
/* ---- the room behind it (2026-09-22): Squarespace's cards are each a
   PLACE, a photographed scene the product sits in; ours were six drawings on
   one night surface, so the set read flat. Bookings is the first card to get
   its own place, drawn rather than photographed (no stock): Rawda Spa's
   treatment room at dusk. Lamplight comes through a mashrabiya arch, falls
   across the stone floor in the lattice's pattern, and reaches the bed and a
   steaming stone bowl. The wall stays dark at top-left, where the text is.
   Positions are % of the card (it changes shape on phones); sizes are cqi. */
.scene { position: absolute; inset: 0; overflow: hidden; z-index: 0; }   /* its own layer: nothing in a room draws over the interface */
.scene--spa {
  --floor: 60%;
  background:
    radial-gradient(ellipse 40cqi 34cqi at 66% 30%, var(--color-spa-lamp-haze), transparent 70%),
    radial-gradient(ellipse 60cqi 20cqi at 40% var(--floor), oklch(78% 0.11 65 / 0.12), transparent 70%),
    linear-gradient(180deg,
      var(--color-spa-wall-top) 0%, var(--color-spa-wall) calc(var(--floor) - 0.5%),
      var(--color-spa-reveal) calc(var(--floor) - 0.5%), var(--color-spa-reveal) var(--floor),   /* the plinth line */
      var(--color-spa-floor) var(--floor), var(--color-spa-floor-2) 100%);
}
.scene > * { position: absolute; }
/* plaster and stone aren't flat: a faint grain over the whole room (shared with the night scene, below) */

/* the arch: lamplight behind a lattice, set in a deep plaster reveal */
.spa__arch {
  inset-inline-start: 59%; inset-block-start: 9%;
  inline-size: 15cqi; block-size: calc(var(--floor) - 9%);
  border-radius: 7.5cqi 7.5cqi 0 0;
  background:
    radial-gradient(ellipse 55% 40% at 50% 42%, oklch(97% 0.03 85 / 0.55), transparent 75%),   /* the bloom washes out the screen's centre */
    repeating-linear-gradient(45deg, transparent 0 0.62cqi, var(--color-spa-lattice) 0.62cqi 0.8cqi),
    repeating-linear-gradient(-45deg, transparent 0 0.62cqi, var(--color-spa-lattice) 0.62cqi 0.8cqi),
    radial-gradient(ellipse 80% 60% at 50% 40%, var(--color-spa-lamp-hi), var(--color-spa-lamp) 55%, var(--color-spa-lamp-deep));
  box-shadow:
    inset 0 0 0 0.9cqi var(--color-spa-reveal),
    inset 0 0 0 1.3cqi var(--color-spa-wall-top),
    0 0 9cqi 1cqi var(--color-spa-lamp-haze);
}
/* the same lattice, thrown forward across the floor */
.spa__beam {
  inset-inline-start: 0; inset-block-start: var(--floor);
  inline-size: 78cqi; block-size: calc(100% - var(--floor));
  clip-path: polygon(76% 0, 95% 0, 46% 100%, 6% 100%);
  background:
    repeating-linear-gradient(30deg, transparent 0 1.6cqi, var(--color-spa-floor) 1.6cqi 2.1cqi),
    repeating-linear-gradient(-60deg, transparent 0 1.6cqi, var(--color-spa-floor) 1.6cqi 2.1cqi),
    linear-gradient(180deg, oklch(80% 0.11 70 / 0.42), oklch(80% 0.11 70 / 0.14));
}
/* the arch's light caught on the polished floor */
.spa__glint {
  inset-inline-start: 57%; inset-block-start: var(--floor);
  inline-size: 19cqi; block-size: 10cqi;
  background: radial-gradient(ellipse 45% 70% at 50% 0, oklch(85% 0.09 75 / 0.45), transparent 70%);
}

/* the treatment bed: linen over a walnut base, a sage towel folded at its foot */
.spa__bed {
  inset-inline-start: 4%; inset-block-start: calc(var(--floor) - 5cqi);
  inline-size: 27cqi; block-size: 3cqi;
  border-radius: 0.8cqi 0.8cqi 0.3cqi 0.3cqi;
  background: linear-gradient(180deg, var(--color-spa-linen) 0 34%, oklch(86% 0.014 82) 34%, var(--color-spa-linen-2) 100%);   /* top face, then the front */
  box-shadow:
    0 2.6cqi 0 -0.2cqi var(--color-spa-wood),                    /* the base */
    0 5.5cqi 2.4cqi -1.2cqi oklch(10% 0.01 60 / 0.8),             /* its shadow on the floor */
    -3cqi -1.5cqi 6cqi oklch(80% 0.11 70 / 0.10);
}
.spa__bed::before, .spa__bed::after {                            /* legs */
  content: ""; position: absolute; inset-block-start: 4cqi;
  inline-size: 1cqi; block-size: 3.4cqi; background: var(--color-spa-wood);
}
.spa__bed::before { inset-inline-start: 2cqi; }
.spa__bed::after  { inset-inline-end: 2cqi; }
.spa__fold {
  position: absolute; inset-inline-end: 2.5cqi; inset-block-end: 100%;
  inline-size: 7cqi; block-size: 1.3cqi; border-radius: 0.4cqi 0.4cqi 0 0;
  background: linear-gradient(180deg, var(--color-spa-sage), oklch(50% 0.04 145));
  box-shadow: 0 -1.1cqi 0 -0.15cqi oklch(66% 0.04 145);          /* a second fold on top */
}
.spa__roll {
  position: absolute; inset-inline-start: 2cqi; inset-block-end: 100%;
  inline-size: 5.5cqi; block-size: 2.2cqi; border-radius: 1.1cqi;
  background: radial-gradient(ellipse 30% 60% at 18% 50%, var(--color-spa-linen-2), transparent 90%), linear-gradient(180deg, var(--color-spa-linen), var(--color-spa-linen-2));
}

/* the hammam bowl on a low stool, and its steam */
.spa__bowl {
  inset-inline-start: 9%; inset-block-start: calc(var(--floor) + 11cqi);
  inline-size: 9cqi; block-size: 3.4cqi;
  border-radius: 0 0 4.5cqi 4.5cqi / 0 0 3.4cqi 3.4cqi;
  background: linear-gradient(180deg, var(--color-spa-stone), oklch(30% 0.01 80));
  box-shadow: 0 1.4cqi 1.6cqi -0.6cqi oklch(10% 0.01 60 / 0.7);
}
.spa__bowl::before {                                             /* water, catching the lamp */
  content: ""; position: absolute; inset-inline: 0.4cqi; inset-block-start: -0.3cqi; block-size: 0.7cqi;
  border-radius: 50%; background: linear-gradient(90deg, oklch(40% 0.02 140), oklch(75% 0.08 70));
}
.steam { position: absolute; inset-inline-start: 50%; inset-block-end: 100%; inline-size: 0; block-size: 0; }
.steam i {
  position: absolute; inset-block-end: 0; inset-inline-start: -2cqi;
  inline-size: 5cqi; block-size: 12cqi; border-radius: 50%;
  background: radial-gradient(ellipse at 50% 60%, var(--color-spa-steam), transparent 70%);
  opacity: 0.7; transform: translate(0.5cqi, -3cqi);
}
.steam i:nth-child(2) { inset-inline-start: -3cqi; }
.steam i:nth-child(3) { inset-inline-start: -1cqi; }
/* The steam holds still, at every width (owner, 2026-10-08: "I'd rather the
   still, smoother version"). Moving, blurred and started as its card
   arrived, it made Safari rebuild the card: Online store and Bookings showed
   their room without text or mock-ups for ~0.2s as they settled (iPhone
   2026-09-30, fixed there first; a MacBook 2026-10-08, still there after
   letting it run on every card). The blurs on the spa's floor beam, glint
   and steam went with it, and the spa's grain below: the gradients under
   them are already soft. Other cards keep their gentle motion. */

/* one candle on the floor, the warmest point in the room */
.spa__candle {
  inset-inline-start: 20%; inset-block-start: calc(var(--floor) + 11.6cqi);
  inline-size: 1.8cqi; block-size: 2.6cqi; border-radius: 0.2cqi;
  background: linear-gradient(90deg, var(--color-spa-linen-2), var(--color-spa-linen));
  box-shadow: 0 0 5cqi 1.5cqi oklch(80% 0.12 65 / 0.22);
}
.spa__candle::before {
  content: ""; position: absolute; inset-inline-start: 50%; inset-block-end: 100%;
  inline-size: 0.6cqi; block-size: 1.1cqi; translate: -50% -0.15cqi;
  border-radius: 50% 50% 50% 50% / 70% 70% 30% 30%;
  background: radial-gradient(ellipse at 50% 70%, var(--color-spa-lamp-hi), var(--color-spa-lamp) 60%, transparent);
}

.fl__tick { inline-size: 1.6cqi; aspect-ratio: 1; border-radius: 50%; background: var(--color-ink); position: relative; }
.fl__tick::after { content: ""; position: absolute; inset-inline-start: 38%; inset-block-start: 22%; inline-size: 26%; block-size: 44%; border: solid var(--color-paper); border-width: 0 0.25cqi 0.25cqi 0; transform: rotate(45deg); }

/* 3b · AI agents (2026-09-22) — the tab is broad ("AI agents": anything an
   agent or an automation can run), the picture is one vivid case. A customer
   messages Rawda Spa (the Bookings sample) on WhatsApp at 11:42 pm, in
   Arabic; the agent answers in Arabic, offers slots and books. Beside it,
   what happened behind the scenes, and the hand-over to a person — the
   page's own argument (speed from the machine, taste from the human) done as
   a feature. Pure Layoutics work, so no "Built on" line. The chat borrows
   WhatsApp's layout and bubble colours, not its mark. */
/* a half frame, on the reference: larger, cropped by the card's bottom edge */
.iph.iph--chat { --w: 30cqi; inset-inline-end: 21cqi; inset-block-start: 16cqi; z-index: 1; }
.iph--chat .iph__screen { background: var(--color-wa-bg); }
.wa__head {
  flex: none; display: flex !important; align-items: center; gap: calc(var(--pt) * 10);
  padding: calc(var(--pt) * 2) calc(var(--pt) * 14) calc(var(--pt) * 10);
  background: var(--color-paper); border-block-end: var(--rule-hair) solid var(--color-rule-2);
}
.wa__head svg { inline-size: calc(var(--pt) * 20); color: var(--color-wa-accent); }
.wa__avatar {
  flex: none; inline-size: calc(var(--pt) * 38); aspect-ratio: 1; border-radius: 50%;
  display: grid !important; place-items: center; font-style: normal; font-weight: 600; font-size: calc(var(--pt) * 16);
  background: var(--color-spa-sage); color: var(--color-paper);
}
.wa__head b { font-weight: 600; font-size: calc(var(--pt) * 16); }
.wa__head em { font-size: calc(var(--pt) * 12); color: var(--color-wa-accent); }
.wa__chat { flex: 1; display: flex !important; flex-direction: column; gap: calc(var(--pt) * 8); padding: calc(var(--pt) * 12) calc(var(--pt) * 12) 0; }
.wa__day {
  align-self: center; padding: calc(var(--pt) * 4) calc(var(--pt) * 10); border-radius: calc(var(--pt) * 8);
  background: var(--color-paper); font-size: calc(var(--pt) * 11); color: var(--color-ios-label-2);
}
.wa__msg {
  position: relative; max-inline-size: 82%;
  padding: calc(var(--pt) * 7) calc(var(--pt) * 10) calc(var(--pt) * 16);
  border-radius: calc(var(--pt) * 12); font-size: calc(var(--pt) * 15); line-height: 1.3;
  box-shadow: 0 calc(var(--pt) * 1) calc(var(--pt) * 1) oklch(17% 0.012 45 / 0.12);
}
.wa__msg[lang="ar"] { font-size: calc(var(--pt) * 16); }
.wa__msg--out { align-self: flex-end; background: var(--color-wa-out); border-end-end-radius: calc(var(--pt) * 3); }
.wa__msg--in  { align-self: flex-start; background: var(--color-paper); border-end-start-radius: calc(var(--pt) * 3); }
.wa__msg > em {
  position: absolute; inset-block-end: calc(var(--pt) * 4); inset-inline-end: calc(var(--pt) * 8);
  font-size: calc(var(--pt) * 10); color: var(--color-ios-label-2); direction: ltr;
}
.wa__msg[dir="rtl"] > em { inset-inline-end: auto; inset-inline-start: calc(var(--pt) * 8); }
.wa__slots { display: flex !important; gap: calc(var(--pt) * 6); margin-block-start: calc(var(--pt) * 8); }
.wa__slots b {
  padding: calc(var(--pt) * 6) calc(var(--pt) * 10); border-radius: calc(var(--pt) * 14);
  border: calc(var(--pt) * 1.2) solid var(--color-wa-accent); color: var(--color-wa-accent-deep);
  font-weight: 600; font-size: calc(var(--pt) * 13);
}
.wa__slots b.is-on { background: var(--color-wa-accent); color: var(--color-paper); }
.wa__card { inline-size: 82%; display: grid !important; gap: calc(var(--pt) * 3); font-size: calc(var(--pt) * 13); }
.wa__ok { display: flex !important; align-items: center; gap: calc(var(--pt) * 6); font-size: calc(var(--pt) * 15); }
.wa__ok b { font-weight: 700; }
.wa__ok i[lang] { display: inline; font-style: normal; }
.wa__ok .zt__tick { inline-size: calc(var(--pt) * 18); background: var(--color-wa-accent); }
.wa__ok .zt__tick::after { border-width: 0 calc(var(--pt) * 2) calc(var(--pt) * 2) 0; }
.wa__sub { color: var(--color-ios-label-2); font-size: calc(var(--pt) * 12); }
.wa__input {
  flex: none; display: flex !important; align-items: center; gap: calc(var(--pt) * 10);
  margin-block-start: auto; padding: calc(var(--pt) * 10) calc(var(--pt) * 14) calc(var(--pt) * 38);
  background: var(--color-paper);
}
.wa__input i { inline-size: calc(var(--pt) * 24); aspect-ratio: 1; border-radius: 50%; border: calc(var(--pt) * 2) solid var(--color-wa-accent); flex: none; }
.wa__input span { flex: 1; padding: calc(var(--pt) * 8) calc(var(--pt) * 14); border-radius: calc(var(--pt) * 18); border: var(--rule-hair) solid var(--color-rule); color: var(--color-ios-label-2); }

/* the crew (2026-09-26): WhatsApp is the example, not the limit. One
   business, four agents, each with last night's result. Only work that is
   quick to set up is shown (owner's rule): no phone agent, no Snapchat, no
   invoice reading. The reviews agent drafts; a person posts. */
.fl--flow { inset-inline-start: 25cqi; inset-block-end: 9cqi; inline-size: 23cqi; z-index: 2; }
.crew { display: grid; gap: 0.2cqi; }
.crew > span {
  display: grid; grid-template-columns: 2.6cqi minmax(0, 1fr); column-gap: 1cqi; align-items: center;
  padding-block: 0.7cqi; border-block-start: var(--rule-hair) solid var(--color-rule-2);
}
.crew > span:first-child { border-block-start: 0; padding-block-start: 0; }
.crew b { font-weight: 600; font-size: 1.05cqi; }
.crew em { grid-column: 2; font-size: 0.95cqi; color: var(--color-ink-2); }
.crew__ico {
  grid-row: span 2; inline-size: 2.6cqi; aspect-ratio: 1; border-radius: var(--radius-xs);
  display: grid !important; place-items: center; background: var(--color-ink); color: var(--color-paper);
}
.crew__ico--wa { background: var(--color-wa-accent); }
.crew__ico svg { inline-size: 62%; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.fl--hand {
  /* the owner's morning notification: what the agent did overnight, and
     what it left for a person. (It was a "Handed to Sara" chip first; the
     owner couldn't read it, so it's now the thing everyone reads daily.) */
  inset-inline-end: 3cqi; inset-block-start: 51cqi; z-index: 2; inline-size: 21cqi;   /* beside the Booked card, clear of every message */
  display: flex; align-items: center; gap: 1.1cqi; padding: 1.1cqi 1.3cqi; border-radius: 2cqi;
  background: oklch(96.5% 0.006 60 / 0.9); -webkit-backdrop-filter: blur(1.2cqi) saturate(1.4); backdrop-filter: blur(1.2cqi) saturate(1.4);
  font-size: 0.95cqi; line-height: 1.3;
}
.fl--hand .push__body > b { font-weight: 600; }
.hand__face {
  flex: none; inline-size: 3.4cqi; aspect-ratio: 1; border-radius: 0.8cqi;
  display: grid !important; place-items: center; font-style: normal; font-weight: 600; font-size: 1.4cqi;
  background: var(--color-spa-sage); color: var(--color-paper);
}
.more.is-live .mcard.is-active .fl--flow, .more.is-live .mcard.is-active .fl--hand { transition-delay: 0.15s; }

/* the room (revised the same day, on the owner's ClickUp reference): no
   props. The shutter, sign and padlock tried too hard; here the light does
   the work — midnight teal where the text sits, warming to an amber glow
   behind the phone, as if its screen lights the dark — and a fine grain. */
.scene--night {
  background:
    radial-gradient(ellipse 58cqi 50cqi at 70% 92%, var(--color-night-glow), transparent 72%),
    radial-gradient(ellipse 50cqi 40cqi at 96% 10%, var(--color-night-glow-2), transparent 70%),
    linear-gradient(160deg, var(--color-night-sky-top) 0%, var(--color-night-sky) 55%, var(--color-night-sky-low) 100%);
}
/* …but not an empty one (the owner, the same day: every neighbour has a
   room behind it). So: Rawda Spa's reception after closing, told with three
   quiet things — a tall window onto the city at night, the empty counter,
   a plant — and no symbols. The phone's glow is the only thing awake. */
.scene--night { --floor: 76%; }
.night__window {
  inset-inline-end: -3cqi; inset-block-start: 15%;   /* clear of the Sample tag */
  inline-size: 22cqi; block-size: calc(var(--floor) - 15%);
  background:
    linear-gradient(90deg, transparent 48.5%, var(--color-night-frame) 48.5% 51.5%, transparent 51.5%),
    radial-gradient(circle at 20% 72%, var(--color-night-bokeh) 0 0.5cqi, transparent 1.4cqi),
    radial-gradient(circle at 34% 80%, var(--color-night-bokeh) 0 0.35cqi, transparent 1.1cqi),
    radial-gradient(circle at 63% 76%, var(--color-night-bokeh-2) 0 0.45cqi, transparent 1.3cqi),
    radial-gradient(circle at 78% 86%, var(--color-night-bokeh) 0 0.3cqi, transparent 1cqi),
    radial-gradient(circle at 88% 70%, var(--color-night-bokeh-2) 0 0.35cqi, transparent 1.2cqi),
    radial-gradient(circle at 12% 90%, var(--color-night-bokeh-2) 0 0.3cqi, transparent 1cqi),
    linear-gradient(180deg, var(--color-night-out-top), var(--color-night-out) 70%, var(--color-night-out-low));
  box-shadow: inset 0 0 0 0.9cqi var(--color-night-frame), 0 0 9cqi 0.5cqi var(--color-night-glow-2);
}
.night__counter {
  inset-inline-start: 0; inset-block: var(--floor) 0; inline-size: 44cqi;
  border-block-start: 1.1cqi solid var(--color-night-stone);
  border-start-end-radius: 1.2cqi;
  background:
    repeating-linear-gradient(90deg, oklch(8% 0.02 220 / 0.35) 0 0.25cqi, transparent 0.25cqi 1.6cqi),
    linear-gradient(180deg, var(--color-night-wood), var(--color-night-sky-top));
  box-shadow: 0 -0.3cqi 2cqi oklch(64% 0.11 60 / 0.18);
}
.night__plant { inset-inline-start: 8cqi; inset-block-start: calc(var(--floor) - 1cqi); inline-size: 0; block-size: 0; }
.night__plant i {
  position: absolute; inset-block-end: 0; inset-inline-start: 0;
  inline-size: 3.2cqi; block-size: 17cqi; border-radius: 50% 50% 50% 50% / 80% 80% 20% 20%;
  background: linear-gradient(90deg, var(--color-night-leaf), var(--color-night-leaf-2));
  transform-origin: 50% 100%;
}
.night__plant i:nth-child(1) { transform: translateX(-1.6cqi) rotate(-24deg); block-size: 14cqi; }
.night__plant i:nth-child(2) { transform: translateX(-1.6cqi) rotate(-9deg); block-size: 19cqi; }
.night__plant i:nth-child(3) { transform: translateX(-1.6cqi) rotate(6deg); block-size: 21cqi; }
.night__plant i:nth-child(4) { transform: translateX(-1.6cqi) rotate(19deg); block-size: 16cqi; }
.night__plant i:nth-child(5) { transform: translateX(-1.6cqi) rotate(33deg); block-size: 12cqi; }
.night__plant i:nth-child(6) { transform: translateX(-1.6cqi) rotate(-38deg); block-size: 10cqi; }

.scene--night::after {             /* the grain; gone from the spa with its blurs (see .steam) */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0.55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: soft-light; opacity: 0.5;
}

/* 3 · invoicing & ERP (reworked 2026-09-22) — the invoice is the way in,
   the ERP is the depth. A bilingual Saudi tax invoice (VAT 15%, the ZATCA
   QR) with its clearance chip, in front of the ERP it lives in: a drawn
   BizArch ERP dashboard (2026-09-26, replacing a rail of module toggles). Built on BizArch ERP (the partner company, named
   on the card's own "Built on" line); every enquiry still comes through our
   form. Figures carry no currency, like every sample here. */
.mk--inv { inline-size: 30cqi; inset-inline-start: 18cqi; inset-inline-end: auto; inset-block-start: 31cqi; inset-block-end: auto; padding: 2cqi 2.4cqi; z-index: 1; }   /* in front of the ERP, whole, Total included */
/* in front of the ERP the invoice keeps what proves it: the bilingual head,
   the lines, VAT 15%, the QR and the Total. The reference row, the column
   heads and the subtotal go (the lines still add up to what is shown). */
.mk--inv :is(.inv__meta, .inv__row--head, .inv__sums > span:first-child) { display: none; }
.mk--inv .qr { inline-size: 6cqi; }
.mk--inv .inv__sums { inline-size: 64%; }
.mk--inv .inv__total { display: grid !important; justify-items: end; row-gap: 0.3cqi; }   /* the label on its own line, the amount under it */
.mk--inv .inv__total em { justify-self: start; white-space: nowrap; }
.inv { display: flex; flex-direction: column; gap: 1cqi; }
.inv i[lang] { display: inline; font-style: normal; letter-spacing: 0; text-transform: none; }
.inv__top { display: flex; justify-content: space-between; align-items: flex-end; padding-block-end: 1.2cqi; border-block-end: var(--rule-bold) solid var(--color-ink); }
.inv__title { display: flex !important; flex-direction: column; align-items: flex-end; gap: 0.2cqi; }
.inv__title b { font-family: var(--font-mono); font-weight: 500; font-size: 0.9cqi; letter-spacing: 0.03em; text-transform: uppercase; }
.inv__title b[lang] { font-family: var(--font-body); font-weight: 600; font-size: 1.35cqi; letter-spacing: 0; }
.inv__meta { display: grid; grid-template-columns: 0.9fr 1fr 1.3fr; gap: 1.6cqi; font-size: 1cqi; font-variant-numeric: tabular-nums; }
.inv__meta em { display: block; font-family: var(--font-mono); font-size: 0.72cqi; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); margin-block-end: 0.3cqi; white-space: nowrap; }
.inv__row { display: grid; grid-template-columns: 1fr 3cqi 8cqi; gap: 1cqi; font-size: 1.05cqi; padding-block: 0.6cqi; border-block-end: var(--rule-hair) solid var(--color-rule-2); font-variant-numeric: tabular-nums; }
.inv__row span:nth-child(n+2) { text-align: end; }
.inv__row--head { font-family: var(--font-mono); font-size: 0.8cqi; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.inv__foot { display: flex; justify-content: space-between; align-items: flex-end; gap: 2cqi; margin-block-start: 0.4cqi; }
.qr { flex: none; inline-size: 7.4cqi; }
.qr path { fill: var(--color-ink); }
.qr__bg { fill: var(--color-paper); }
.inv__sums { display: grid; gap: 0.5cqi; inline-size: 52%; font-size: 1.05cqi; font-variant-numeric: tabular-nums; }
.inv__sums > span { display: flex; justify-content: space-between; align-items: baseline; }
.inv__sums em { font-family: var(--font-mono); font-size: 0.78cqi; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.inv__total {
  padding-block-start: 0.7cqi; border-block-start: var(--rule-bold) solid var(--color-ink);
  font-family: var(--font-display); font-variation-settings: "opsz" 36, "SOFT" 0, "WONK" 0; font-weight: 600; font-size: 1.8cqi;
}
/* one chip on the invoice's corner, like the Booked chip on the spa card */
.fl--zatca {
  inset-inline-start: 14cqi; inset-block-start: 28.5cqi; z-index: 2;
  display: flex; align-items: center; gap: 0.9cqi;
  padding: 1cqi 1.6cqi; font-size: 1.05cqi; font-weight: 600;
}
.zt__tick { flex: none; inline-size: 1.5cqi; aspect-ratio: 1; border-radius: 50%; background: var(--color-ink); position: relative; }
.zt__tick::after { content: ""; position: absolute; inset-inline-start: 38%; inset-block-start: 22%; inline-size: 26%; block-size: 44%; border: solid var(--color-paper); border-width: 0 0.22cqi 0.22cqi 0; transform: rotate(45deg); }
/* the ERP behind it, drawn on BizArch ERP's own dashboard (studied from
   the owner's screenshot; no real customer or figure from it is used): the
   dark sidebar is the module list, so the growth story needs no toggles.
   Qirmid's figures are the sample's own. BizArch blue is theirs, like
   Sirb's saffron; it never stands in for our vermilion. */
.mk--erp {
  inline-size: 47cqi; inset-inline-end: 3.5cqi; inset-block-start: 6.5cqi; inset-block-end: auto;
  padding: 0; overflow: hidden;
  display: grid !important; grid-template-columns: 11cqi minmax(0, 1fr);
}
.erp__side {
  display: flex !important; flex-direction: column; gap: 0.35cqi;
  padding: 1.6cqi 1cqi; background: var(--color-bizarch-side); color: var(--color-bizarch-side-ink);
  font-size: 0.95cqi;
}
.erp__brand { display: flex !important; align-items: center; gap: 0.7cqi; margin-block-end: 1.2cqi; font-weight: 600; font-size: 1.05cqi; color: var(--color-paper); white-space: nowrap; }
.erp__mark { flex: none; display: grid !important; place-items: center; inline-size: 2cqi; aspect-ratio: 1; border-radius: 0.5cqi; background: var(--color-bizarch); color: var(--color-paper); font-style: normal; font-weight: 700; font-size: 1.1cqi; }
.erp__side em { padding: 0.55cqi 0.7cqi; border-radius: 0.4cqi; white-space: nowrap; }
.erp__side em.is-on { background: var(--color-bizarch-tint); color: var(--color-bizarch); font-weight: 600; }
.erp__main { display: flex !important; flex-direction: column; gap: 1.1cqi; padding: 1.4cqi 1.8cqi 2cqi; min-inline-size: 0; }
.erp__bar { display: flex !important; gap: 1cqi; font-size: 0.85cqi; color: var(--color-muted); }
.erp__search { flex: 1; padding: 0.5cqi 0.9cqi; border: var(--rule-hair) solid var(--color-rule); border-radius: 0.5cqi; }
.erp__co { padding: 0.5cqi 0.9cqi; border: var(--rule-hair) solid var(--color-rule); border-radius: 0.5cqi; color: var(--color-ink-2); white-space: nowrap; }
.erp__head { display: flex !important; align-items: center; justify-content: space-between; gap: 1cqi; }
.erp__head b { font-weight: 700; font-size: 1.6cqi; letter-spacing: -0.01em; }
.erp__tabs { display: flex !important; gap: 0.3cqi; font-size: 0.85cqi; color: var(--color-ink-2); }
.erp__tabs em { padding: 0.4cqi 0.8cqi; border-radius: 0.4cqi; white-space: nowrap; }
.erp__tabs em.is-on { background: var(--color-bizarch); color: var(--color-paper); }
.erp__k { font-family: var(--font-mono); font-size: 0.75cqi; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.erp__kpis { display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1cqi; margin-block-start: -0.4cqi; }
.erp__kpis > span { position: relative; display: flex !important; flex-direction: column; gap: 0.35cqi; padding: 1cqi 1.1cqi; border: var(--rule-hair) solid var(--color-rule); border-radius: 0.6cqi; }
.erp__kpis em { font-family: var(--font-mono); font-size: 0.72cqi; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); white-space: nowrap; }
.erp__kpis b { font-weight: 700; font-size: 1.7cqi; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.erp__up { position: absolute; inset-inline-end: 1.1cqi; inset-block-start: 1cqi; font-style: normal; font-size: 0.8cqi; font-weight: 600; color: var(--color-bizarch-up); }
.erp__up::before { content: "▲ "; font-size: 0.8em; }
.erp__chart { display: flex !important; flex-direction: column; gap: 0.7cqi; padding: 1cqi 1.1cqi; border: var(--rule-hair) solid var(--color-rule); border-radius: 0.6cqi; }
.erp__chart em { font-family: var(--font-mono); font-size: 0.72cqi; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.erp__bars { display: flex !important; align-items: flex-end; gap: 1cqi; block-size: 6cqi; }
.erp__bars i { flex: 1; block-size: var(--h); border-radius: 0.3cqi 0.3cqi 0 0; background: var(--color-bizarch-tint); }
.erp__bars i.is-on { background: var(--color-bizarch); }
.erp__bars i:nth-child(1) { --h: 42%; } .erp__bars i:nth-child(2) { --h: 55%; } .erp__bars i:nth-child(3) { --h: 48%; }
.erp__bars i:nth-child(4) { --h: 66%; } .erp__bars i:nth-child(5) { --h: 72%; } .erp__bars i:nth-child(6) { --h: 88%; }

/* the room: a contractor's desk at night — walnut, a brass architect's
   lamp, a hard hat and rolled drawings in its pool of light */
.scene--desk {
  --top: 70%;
  background:
    radial-gradient(ellipse 34cqi 22cqi at 15% 64%, var(--color-cafe-lamp-haze), transparent 70%),
    linear-gradient(180deg, var(--color-desk-wall-top) 0%, var(--color-desk-wall) var(--top));
}
.desk__top {
  inset-inline: 0; inset-block: var(--top) 0;
  border-block-start: 0.45cqi solid var(--color-desk-edge);
  background:
    repeating-linear-gradient(176deg, transparent 0 0.9cqi, oklch(10% 0.02 45 / 0.16) 0.9cqi 1.05cqi),
    linear-gradient(180deg, var(--color-desk-walnut), var(--color-desk-walnut-2));
}
.desk__pool {
  inset-inline-start: 0; inset-block-start: var(--top); inline-size: 36cqi; block-size: 14cqi; z-index: 1;
  background: radial-gradient(ellipse 50% 60% at 45% 20%, oklch(88% 0.11 80 / 0.34), transparent 70%);
}
.desk__lamp {
  inset-inline-start: 5cqi; inset-block-start: calc(var(--top) - 0.8cqi); z-index: 2;
  inline-size: 5cqi; block-size: 1.2cqi; border-radius: 1cqi 1cqi 0.2cqi 0.2cqi;
  background: linear-gradient(180deg, var(--color-cafe-brass), var(--color-cafe-brass-2));
}
.desk__lamp::before {            /* the arm */
  content: ""; position: absolute; inset-inline-start: 2.3cqi; inset-block-end: 100%;
  inline-size: 0.45cqi; block-size: 11cqi; background: linear-gradient(90deg, var(--color-cafe-brass), var(--color-cafe-brass-2));
  transform: rotate(22deg); transform-origin: bottom;
}
.desk__lamp::after {             /* the shade, lit from under */
  content: ""; position: absolute; inset-inline-start: 4.8cqi; inset-block-end: calc(100% + 8.6cqi);
  inline-size: 5.4cqi; block-size: 3cqi;
  clip-path: polygon(30% 0, 70% 0, 100% 100%, 0 100%);
  background: linear-gradient(180deg, var(--color-cafe-brass), var(--color-cafe-brass-2) 80%, var(--color-cafe-lamp) 80%);
  transform: rotate(28deg);
  filter: drop-shadow(0 1cqi 2cqi oklch(88% 0.11 80 / 0.6));
}
.desk__hat {
  inset-inline-start: 15cqi; inset-block-start: calc(var(--top) + 1.4cqi); z-index: 2;
  inline-size: 8cqi; block-size: 4.2cqi;
  border-radius: 50% 50% 8% 8% / 100% 100% 8% 8%;
  background: radial-gradient(ellipse at 38% 30%, var(--color-desk-hat-hi), var(--color-desk-hat) 55%, var(--color-desk-hat-2));
  box-shadow: 0 1.6cqi 1.4cqi -0.8cqi oklch(8% 0.02 45 / 0.7);
}
.desk__hat::before {             /* the ridge */
  content: ""; position: absolute; inset-inline-start: calc(50% - 0.7cqi); inset-block: 0.3cqi 0;
  inline-size: 1.4cqi; border-radius: 0.7cqi 0.7cqi 0 0; background: oklch(100% 0 0 / 0.18);
}
.desk__hat::after {              /* the brim */
  content: ""; position: absolute; inset-inline: -1.2cqi -2cqi; inset-block-end: -0.5cqi; block-size: 1.1cqi;
  border-radius: 50%; background: linear-gradient(180deg, var(--color-desk-hat), var(--color-desk-hat-2));
}
.desk__rolls { inset-inline-start: 1cqi; inset-block-start: calc(var(--top) + 7.5cqi); inline-size: 26cqi; block-size: 7cqi; z-index: 2; }
.desk__rolls i {
  position: absolute; inline-size: 22cqi; block-size: 2.1cqi; border-radius: 1.05cqi;
  background:
    radial-gradient(circle at 1.05cqi 50%, var(--color-desk-blue) 0 0.35cqi, var(--color-desk-paper-2) 0.4cqi 0.9cqi, transparent 0.95cqi),
    linear-gradient(180deg, var(--color-desk-paper), var(--color-desk-paper-2));
  box-shadow: 0 0.8cqi 0.8cqi -0.4cqi oklch(8% 0.02 45 / 0.6);
}
.desk__rolls i:nth-child(1) { inset-block-start: 0; inset-inline-start: 2cqi; }
.desk__rolls i:nth-child(2) { inset-block-start: 1.9cqi; inset-inline-start: 0; }
.desk__rolls i:nth-child(3) { inset-block-start: 3.8cqi; inset-inline-start: 3cqi; inline-size: 19cqi; }

/* 4 · apps — Darb, a coffee-delivery sample, rebuilt 2026-09-22 after a
   study of real iOS screens (Mobbin's showcase: Uber, Airbnb, Headspace…).
   What made theirs read as real and ours as a wireframe: the device itself
   (status bar, Dynamic Island, home indicator, true 390×844 proportions),
   one visual anchor per screen (a map, a photo), and the stock iOS patterns
   — a bottom sheet with a grabber, pill buttons, a tab bar. So: everything
   inside a phone is sized in iOS points off the phone's own width (--pt),
   and the front screen is an order brought out to the car (it was live
   tracking on a drawn map until 2026-09-26). Darb has its own
   saffron (not our vermilion, which only ever corrects). Radii here are
   the device's, not the page's 2px: the drawing depicts iOS. */
.iph {
  --w: 25cqi; --pt: calc(var(--w) / 410);
  position: absolute; inline-size: var(--w);
  padding: calc(var(--pt) * 10);
  border-radius: calc(var(--pt) * 64);
  background: linear-gradient(135deg, var(--color-iph-frame-2), var(--color-iph-frame) 30%, var(--color-iph-frame) 70%, var(--color-iph-frame-2));
  box-shadow:
    inset 0 0 0 calc(var(--pt) * 1.5) oklch(100% 0 0 / 0.14),
    0 2.4cqi 4cqi -1cqi oklch(8% 0.02 265 / 0.75),
    0 0.4cqi 1cqi oklch(8% 0.02 265 / 0.4);
  color: var(--color-ink);
  font-family: var(--font-body); font-size: calc(var(--pt) * 15); line-height: 1.25; letter-spacing: -0.01em;
}
.iph--order { inset-inline-end: 25cqi; inset-block-start: 12cqi; z-index: 1; }
.iph--menu  { --w: 22cqi; inset-inline-end: 2.5cqi; inset-block-start: 20cqi; transform: rotate(6deg); }
.iph__screen {
  position: relative; overflow: hidden;
  aspect-ratio: 390 / 844;
  border-radius: calc(var(--pt) * 54);
  background: var(--color-paper);
  display: flex; flex-direction: column;
}
.iph svg { display: block; }

/* the stock iOS chrome */
.ios-bar {
  position: relative; z-index: 2; flex: none;
  display: flex !important; align-items: center; justify-content: space-between;
  block-size: calc(var(--pt) * 54); padding-inline: calc(var(--pt) * 34) calc(var(--pt) * 26);
}
.ios-bar b { font-weight: 600; font-size: calc(var(--pt) * 17); letter-spacing: -0.02em; }
.ios-island {
  position: absolute; left: 50%; inset-block-start: calc(var(--pt) * 11);
  inline-size: calc(var(--pt) * 124); block-size: calc(var(--pt) * 36); translate: -50% 0;
  border-radius: calc(var(--pt) * 20); background: var(--color-pay-apple);
}
.ios-icons { inline-size: calc(var(--pt) * 70); fill: currentColor; }
.ios-home {
  position: absolute; left: 50%; inset-block-end: calc(var(--pt) * 8); translate: -50% 0; z-index: 3;
  inline-size: calc(var(--pt) * 134); block-size: calc(var(--pt) * 5); border-radius: calc(var(--pt) * 3);
  background: var(--color-ink);
}
.ios-tabs {
  margin-block-start: auto; flex: none;
  display: grid !important; grid-template-columns: repeat(4, 1fr); justify-items: center;
  block-size: calc(var(--pt) * 84); padding-block-start: calc(var(--pt) * 10);
  border-block-start: var(--rule-hair) solid var(--color-rule-2);
  background: var(--color-paper);
  color: var(--color-ios-label-2);
}
.ios-tabs svg { inline-size: calc(var(--pt) * 26); fill: none; }
.ios-tabs svg:first-child { fill: currentColor; }
.ios-tabs svg.is-on { color: var(--color-darb-deep); }

/* back phone — the menu */
.dm__head { display: flex !important; align-items: center; justify-content: space-between; padding: calc(var(--pt) * 6) calc(var(--pt) * 20) 0; }
.dm__head em { font-size: calc(var(--pt) * 13); color: var(--color-ios-label-2); }
.dm__brand { font-family: var(--font-display); font-variation-settings: "opsz" 36, "SOFT" 0, "WONK" 0; font-weight: 600; font-size: calc(var(--pt) * 30); line-height: 1.05; letter-spacing: -0.02em; }
.dm__avatar {
  inline-size: calc(var(--pt) * 38); aspect-ratio: 1; border-radius: 50%;
  display: grid !important; place-items: center;
  background: var(--color-darb-tint); color: var(--color-darb-deep); font-style: normal; font-weight: 600; font-size: calc(var(--pt) * 15);
}
.dm__search {
  display: flex !important; align-items: center; gap: calc(var(--pt) * 8);
  margin: calc(var(--pt) * 14) calc(var(--pt) * 20) 0; padding: calc(var(--pt) * 10) calc(var(--pt) * 12);
  border-radius: calc(var(--pt) * 12); background: var(--color-ios-fill); color: var(--color-ios-label-2);
}
.dm__search svg { inline-size: calc(var(--pt) * 16); }
.dm__loyal {
  display: grid !important; gap: calc(var(--pt) * 10);
  margin: calc(var(--pt) * 14) calc(var(--pt) * 20) 0; padding: calc(var(--pt) * 14) calc(var(--pt) * 16);
  border-radius: calc(var(--pt) * 18);
  background: linear-gradient(120deg, var(--color-darb-deep), var(--color-darb));
  color: var(--color-paper);
}
.dm__loyal > span:first-child { display: flex !important; align-items: baseline; justify-content: space-between; font-size: calc(var(--pt) * 13); }
.dm__loyal b { font-size: calc(var(--pt) * 20); font-weight: 700; letter-spacing: -0.02em; margin-inline-end: calc(var(--pt) * 8); }
.dm__cups { display: grid !important; grid-template-columns: repeat(10, 1fr); gap: calc(var(--pt) * 5); }
.dm__cups i { aspect-ratio: 1; border-radius: 50%; border: calc(var(--pt) * 1.5) solid oklch(100% 0 0 / 0.55); }
.dm__cups i.is-on { background: var(--color-paper); border-color: var(--color-paper); }
.dm__chips { display: flex !important; gap: calc(var(--pt) * 8); margin: calc(var(--pt) * 16) calc(var(--pt) * 20) 0; }
.dm__chips em {
  padding: calc(var(--pt) * 7) calc(var(--pt) * 14); border-radius: calc(var(--pt) * 18);
  background: var(--color-ios-fill); font-size: calc(var(--pt) * 14); font-weight: 500;
}
.dm__chips em.is-on { background: var(--color-ink); color: var(--color-paper); }
.dm__grid { display: grid !important; grid-template-columns: 1fr 1fr; gap: calc(var(--pt) * 16) calc(var(--pt) * 12); margin: calc(var(--pt) * 16) calc(var(--pt) * 20) 0; }
.dm__item { position: relative; display: grid !important; gap: calc(var(--pt) * 2); }
.dm__item b { margin-block-start: calc(var(--pt) * 6); font-size: calc(var(--pt) * 14); font-weight: 600; }
.dm__item em { font-size: calc(var(--pt) * 13); color: var(--color-ios-label-2); }
.dm__pic {
  aspect-ratio: 1; border-radius: calc(var(--pt) * 16);
  display: grid !important; place-items: center; overflow: hidden;
  background: radial-gradient(circle at 50% 60%, var(--color-paper), var(--color-darb-tint) 75%);
}
.dm__pic--2 { background: radial-gradient(circle at 50% 60%, var(--color-paper), var(--color-map-park) 80%); }
.dm__pic--3 { background: radial-gradient(circle at 50% 60%, var(--color-paper), var(--color-paper-3) 75%); }
.dm__pic--4 { background: radial-gradient(circle at 50% 60%, var(--color-paper), var(--color-daylight) 85%); }
.dm__add {
  position: absolute; inset-inline-end: calc(var(--pt) * 8); inset-block-start: calc(var(--pt) * 118);
  inline-size: calc(var(--pt) * 30); aspect-ratio: 1; border-radius: 50%;
  background: var(--color-paper); box-shadow: 0 calc(var(--pt) * 2) calc(var(--pt) * 8) oklch(17% 0.012 45 / 0.2);
}
.dm__add::before, .dm__add::after {
  content: ""; position: absolute; left: 50%; inset-block-start: 50%; translate: -50% -50%;
  inline-size: calc(var(--pt) * 12); block-size: calc(var(--pt) * 2.2); border-radius: 1px; background: var(--color-ink);
}
.dm__add::after { rotate: 90deg; }
/* the menu's pictures, drawn: a flat white from above, an iced latte, a
   date loaf, a V60 */
.cup {
  inline-size: 58%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle, var(--color-paper) 0 16%, var(--color-darb-tint) 17% 24%, oklch(55% 0.07 55) 25% 60%, var(--color-paper) 61% 72%, var(--color-paper-3) 73% 76%, var(--color-paper) 77%);
  box-shadow: calc(var(--pt) * 4) calc(var(--pt) * 8) calc(var(--pt) * 14) oklch(17% 0.012 45 / 0.25);
}
.glass {
  inline-size: 34%; aspect-ratio: 0.62; border-radius: calc(var(--pt) * 4) calc(var(--pt) * 4) calc(var(--pt) * 10) calc(var(--pt) * 10);
  background: linear-gradient(180deg, oklch(100% 0 0 / 0.5) 0 12%, oklch(90% 0.03 75) 12% 45%, oklch(60% 0.08 55) 70%, oklch(45% 0.07 50));
  box-shadow: inset calc(var(--pt) * 3) 0 0 oklch(100% 0 0 / 0.45), calc(var(--pt) * 4) calc(var(--pt) * 8) calc(var(--pt) * 12) oklch(17% 0.012 45 / 0.22);
  position: relative;
}
.glass::before { content: ""; position: absolute; inset-inline-start: 58%; inset-block-end: 70%; inline-size: calc(var(--pt) * 4); block-size: 55%; background: var(--color-ink); rotate: 12deg; border-radius: 2px; }
.loaf {
  inline-size: 66%; aspect-ratio: 1.9; border-radius: calc(var(--pt) * 14) calc(var(--pt) * 14) calc(var(--pt) * 6) calc(var(--pt) * 6);
  background:
    radial-gradient(ellipse 9% 14% at 28% 55%, oklch(30% 0.05 40) 90%, transparent),
    radial-gradient(ellipse 9% 14% at 52% 48%, oklch(30% 0.05 40) 90%, transparent),
    radial-gradient(ellipse 9% 14% at 74% 58%, oklch(30% 0.05 40) 90%, transparent),
    linear-gradient(180deg, oklch(52% 0.10 50), oklch(40% 0.08 45));
  box-shadow: calc(var(--pt) * 4) calc(var(--pt) * 8) calc(var(--pt) * 12) oklch(17% 0.012 45 / 0.25);
}
.cone {
  inline-size: 48%; aspect-ratio: 1.2;
  clip-path: polygon(0 0, 100% 0, 62% 78%, 62% 100%, 38% 100%, 38% 78%);
  background: linear-gradient(90deg, var(--color-paper-3), var(--color-paper) 40%, var(--color-paper-2));
  filter: drop-shadow(0 calc(var(--pt) * 6) calc(var(--pt) * 6) oklch(17% 0.012 45 / 0.25));
}

/* front phone — order ahead, brought out to the car (2026-09-26). It was
   live courier tracking; the owner dropped delivery as a saturated market
   and a complex build. Car pickup is how Saudis use cafés, and it needs only
   an order, a status and a notification: no maps, no drivers. The picture,
   redrawn the same day at dusk to match the card: Sirb's front with a
   striped awning, a lit window with the barista at the counter, a glass
   door, a plant, light spilling across the pavement, and the customer's
   car at the kerb, a dotted path from the door to it. */
.po__scene { position: absolute; inset: 0 0 auto; inline-size: 100%; block-size: 60%; }   /* runs under the sheet, so the kerb meets it */
.po__wall    { fill: var(--color-pickup-wall); }
.po__sign    { fill: var(--color-ink); }
.po__sign-t  { fill: var(--color-darb); font-family: var(--font-display); font-weight: 600; font-size: 17px; text-anchor: middle; }
.po__scallop { fill: none; stroke: var(--color-darb-deep); stroke-width: 3; }
.po__barista { fill: var(--color-pickup-barista); }
.po__counter { fill: var(--color-pickup-counter); }
.po__cup     { fill: var(--color-paper); stroke: var(--color-darb-deep); stroke-width: 2; stroke-linejoin: round; }
.po__frame   { fill: none; stroke: var(--color-pickup-frame); stroke-width: 5; }
.po__plant   { fill: var(--color-pickup-leaf); }
.po__pot     { fill: var(--color-pickup-pot); }
.po__pave    { fill: var(--color-pickup-pave); }
.po__road    { fill: var(--color-pickup-road); }
.po__route   { fill: none; stroke: var(--color-darb); stroke-width: 3.5; stroke-linecap: round; stroke-dasharray: 1 8; }
.po__car     { fill: var(--color-pickup-car); stroke: var(--color-pickup-car-edge); stroke-width: 2; stroke-linejoin: round; }
.po__glass   { fill: var(--color-pickup-glass); }
.po__wheel   { fill: var(--color-ink); }
.po__hub     { fill: var(--color-pickup-car-edge); }
/* the status bar sits on the dusk sky here, so it turns light */
.iph--order .ios-bar { color: var(--color-paper); }
.dt__sheet.po__sheet { block-size: 57%; }   /* two classes: the shared .dt__sheet rule comes later */
.po__steps { display: grid !important; grid-template-columns: repeat(3, 1fr); gap: calc(var(--pt) * 6); font-size: calc(var(--pt) * 12); color: var(--color-ios-label-2); }
.po__steps > span { display: flex !important; flex-direction: column; gap: calc(var(--pt) * 6); }
.po__steps i { block-size: calc(var(--pt) * 5); border-radius: 3px; background: var(--color-ios-fill); }
.po__steps .is-on i { background: var(--color-darb-deep); }
.po__steps > span:last-child { color: var(--color-ink); font-weight: 600; }
.po__carface svg { inline-size: 60%; }
.dt__top { position: relative; z-index: 2; display: flex !important; align-items: center; justify-content: space-between; padding: calc(var(--pt) * 4) calc(var(--pt) * 16); }
.dt__back, .dt__eta { box-shadow: 0 calc(var(--pt) * 2) calc(var(--pt) * 10) oklch(17% 0.012 45 / 0.18); background: var(--color-paper); }
.dt__back { inline-size: calc(var(--pt) * 40); aspect-ratio: 1; border-radius: 50%; display: grid !important; place-items: center; }
.dt__back svg { inline-size: calc(var(--pt) * 18); }
.dt__eta { padding: calc(var(--pt) * 9) calc(var(--pt) * 14); border-radius: calc(var(--pt) * 20); font-weight: 600; }
.dt__sheet {
  position: absolute; inset: auto 0 0; block-size: 45%;
  display: flex !important; flex-direction: column; gap: calc(var(--pt) * 10);
  padding: calc(var(--pt) * 10) calc(var(--pt) * 20) 0;
  border-radius: calc(var(--pt) * 28) calc(var(--pt) * 28) 0 0;
  background: var(--color-paper);
  box-shadow: 0 calc(var(--pt) * -4) calc(var(--pt) * 20) oklch(17% 0.012 45 / 0.14);
}
.dt__grab { align-self: center; inline-size: calc(var(--pt) * 36); block-size: calc(var(--pt) * 5); border-radius: 3px; background: var(--color-rule); margin-block-end: calc(var(--pt) * 2); }
.dt__k { font-size: calc(var(--pt) * 13); font-weight: 600; color: var(--color-darb-deep); text-transform: uppercase; letter-spacing: 0.06em; }
.dt__h { font-size: calc(var(--pt) * 26); font-weight: 700; letter-spacing: -0.03em; line-height: 1.05; margin-block-start: calc(var(--pt) * -6); }
.dt__steps { display: grid !important; grid-template-columns: repeat(4, 1fr); gap: calc(var(--pt) * 5); }
.dt__steps i { block-size: calc(var(--pt) * 5); border-radius: 3px; background: var(--color-ios-fill); }
.dt__steps i.is-on { background: var(--color-darb-deep); }
.dt__who {
  display: flex !important; align-items: center; gap: calc(var(--pt) * 10);
  padding-block: calc(var(--pt) * 12); border-block: var(--rule-hair) solid var(--color-rule-2);
}
.dt__face {
  flex: none; inline-size: calc(var(--pt) * 44); aspect-ratio: 1; border-radius: 50%;
  display: grid !important; place-items: center; font-style: normal; font-weight: 600; font-size: calc(var(--pt) * 17);
  background: var(--color-darb-tint); color: var(--color-darb-deep);
}
.dt__name { flex: 1; }
.dt__name b { font-weight: 600; font-size: calc(var(--pt) * 16); }
.dt__name em { font-size: calc(var(--pt) * 13); color: var(--color-ios-label-2); }
.dt__btn { flex: none; inline-size: calc(var(--pt) * 40); aspect-ratio: 1; border-radius: 50%; display: grid !important; place-items: center; background: var(--color-ios-fill); }
.dt__btn svg { inline-size: calc(var(--pt) * 18); }
.dt__btn--call { background: var(--color-darb-deep); color: var(--color-paper); }
.dt__btn--call svg { fill: currentColor; }
.dt__order { display: flex !important; justify-content: space-between; font-size: calc(var(--pt) * 14); }
.dt__order em { color: var(--color-ios-label-2); }
.dt__cta {
  margin-block-start: calc(var(--pt) * 4); padding-block: calc(var(--pt) * 14); text-align: center;
  border-radius: calc(var(--pt) * 26); background: var(--color-ink); color: var(--color-paper);
  font-weight: 600; font-size: calc(var(--pt) * 16);
}

/* the notification — an iOS banner over the scene */
.fl--push {
  /* where iOS puts it: across the top of the order phone, under its island */
  inset-inline-end: 22cqi; inset-block-start: 16.5cqi; inline-size: 29cqi; z-index: 2;
  display: flex; align-items: center; gap: 1.1cqi;
  padding: 1.1cqi 1.3cqi; border-radius: 2cqi;
  background: oklch(96.5% 0.006 60 / 0.86); -webkit-backdrop-filter: blur(1.2cqi) saturate(1.4); backdrop-filter: blur(1.2cqi) saturate(1.4);
  font-size: 0.95cqi; line-height: 1.3;
}
.push__icon { flex: none; inline-size: 3.4cqi; aspect-ratio: 1; border-radius: 0.8cqi; background: linear-gradient(135deg, var(--color-darb), var(--color-darb-deep)); position: relative; }
.push__icon::after {            /* Darb's mark: a road that bends */
  content: ""; position: absolute; inset: 26%; border: 0.35cqi solid var(--color-paper); border-inline-start-color: transparent; border-block-end-color: transparent; border-radius: 0 60% 0 0;
}
.push__body { flex: 1; min-inline-size: 0; }
.push__top { display: flex !important; justify-content: space-between; font-size: 0.8cqi; letter-spacing: 0.04em; text-transform: uppercase; color: var(--color-ink-2); }
.push__top b { font-weight: 500; }
.push__body > b { font-weight: 600; }
.push__body > span:last-child { color: var(--color-ink-2); }

/* 0 · services — the firm's own page: a headline band, three services,
   and the enquiry floating over the band, clear of the services themselves */
.mk--svcs { inset-block-start: 24cqi; inset-block-end: auto; }
.mk__hero {
  display: flex; align-items: flex-end; justify-content: flex-end;
  block-size: 22cqi; margin-block-start: 2cqi; padding: 2.4cqi 2.6cqi;
  border-radius: var(--radius-xs);
  /* a facade of windows, drawn: vertical mullions over a dusk gradient */
  background:
    repeating-linear-gradient(90deg, transparent 0 3.4cqi, oklch(96.5% 0.006 60 / 0.07) 3.4cqi 3.6cqi),
    repeating-linear-gradient(0deg, transparent 0 2.6cqi, oklch(96.5% 0.006 60 / 0.05) 2.6cqi 2.75cqi),
    linear-gradient(160deg, var(--color-ink-2), var(--color-ink) 70%);
}
.mk__hero-h {
  max-inline-size: 18cqi; text-align: end;
  font-family: var(--font-display); font-variation-settings: "opsz" 36, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: 2.3cqi; line-height: 1.05; letter-spacing: var(--track-md);
  color: var(--color-paper);
}
.mk__tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.6cqi; padding-block: 2.2cqi 3cqi; }
.tile { display: flex; flex-direction: column; gap: 0.9cqi; padding-block-start: 1.2cqi; border-block-start: var(--rule-bold) solid var(--color-ink); }
.tile em { font-family: var(--font-mono); font-size: 0.85cqi; letter-spacing: 0.03em; color: var(--color-accent); }
.tile__h { font-weight: 600; font-size: 1.15cqi; white-space: nowrap; }
.fl--enq { inset-inline-start: 30cqi; inset-block-start: 31cqi; inline-size: 20cqi; }   /* inside the band's height: clear of the brand above and the services below */
.fld { display: flex; flex-direction: column; gap: 0.5cqi; margin-block-end: 1cqi; }
.fld em { font-family: var(--font-mono); font-size: 0.75cqi; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.fld i { block-size: 2.4cqi; border: var(--rule-hair) solid var(--color-rule); border-radius: var(--radius-xs); }
.fld--sel span {
  display: flex; align-items: center; justify-content: space-between;
  block-size: 2.4cqi; padding-inline: 0.9cqi;
  border: var(--rule-hair) solid var(--color-ink); border-radius: var(--radius-xs);
}
.fld--sel span::after { content: ""; inline-size: 0.7cqi; block-size: 0.7cqi; border: solid var(--color-ink); border-width: 0 0.2cqi 0.2cqi 0; transform: translateY(-25%) rotate(45deg); }

/* 6 · platforms (2026-09-26, replacing Portfolio) — the idea and the
   thing it became, side by side: the client's pencil sketch of a jobs board
   on grid paper, and the same screen built. The kinds of work the card names
   (portals, dashboards, internal tools) are abstract, so the picture has to
   be one concrete case a visitor can recognise their own idea in. Rasin
   Facilities is an invented sample, web-checked 2026-09-26. */
.mk--plat { inline-size: 54cqi; inset-inline-end: 4cqi; inset-block-start: 27cqi; inset-block-end: auto; padding: 1.8cqi 2.2cqi 2.4cqi; }
.plat__search {
  margin-inline-start: auto; inline-size: 13cqi; padding: 0.5cqi 1cqi;
  border: var(--rule-hair) solid var(--color-rule); border-radius: var(--radius-xs);
  font-size: 0.9cqi; color: var(--color-muted);
}
.plat { display: grid; grid-template-columns: 8.5cqi minmax(0, 1fr); gap: 2cqi; padding-block-start: 1.8cqi; }
.plat__side { display: flex; flex-direction: column; gap: 0.5cqi; }
.plat__side em { padding: 0.6cqi 0.9cqi; font-size: 1cqi; color: var(--color-ink-2); border-radius: var(--radius-xs); }
.plat__side em.is-on { background: var(--color-paper-2); color: var(--color-ink); font-weight: 600; box-shadow: inset 0.25cqi 0 0 var(--color-ink); }
.plat__kpis { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.2cqi; }
.plat__kpis > span { display: flex; flex-direction: column; gap: 0.5cqi; padding: 1.1cqi 1.2cqi; border: var(--rule-hair) solid var(--color-rule); border-radius: var(--radius-xs); }
.plat__kpis em { font-family: var(--font-mono); font-size: 0.78cqi; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); white-space: nowrap; }
.plat__kpis b {
  font-family: var(--font-display); font-variation-settings: "opsz" 36, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: 2.6cqi; line-height: 1;
}
.plat__table { display: flex; flex-direction: column; margin-block-start: 1.6cqi; }
.plat__row {
  display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr) 7.5cqi; align-items: center; gap: 1cqi;
  padding-block: 0.85cqi; border-block-end: var(--rule-hair) solid var(--color-rule-2);
  font-size: 1cqi; white-space: nowrap;
}
.plat__row > span { overflow: hidden; text-overflow: ellipsis; }
.plat__row b { display: inline; font-family: var(--font-mono); font-size: 0.85em; color: var(--color-muted); margin-inline-end: 0.5cqi; }
.plat__row--head { font-family: var(--font-mono); font-size: 0.78cqi; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.st {
  display: inline-block; padding: 0.3cqi 0.8cqi; border-radius: var(--radius-xs);
  font-size: 0.85cqi; font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--color-rule); color: var(--color-ink-2);
}
.st--go   { background: var(--color-plan-go); color: var(--color-plan-go-ink); box-shadow: none; }
.st--done { background: var(--color-plan-done); color: var(--color-plan-done-ink); box-shadow: none; }

/* the sketch: pencil on grid paper, lines drawn a little unevenly so it
   reads as a hand, not a wireframe tool. Tilted with the rotate property,
   so it composes with the shared float-in transform. */
.fl--sketch {
  inset-inline-start: 5cqi; inset-block-end: 4cqi; inline-size: 29cqi;
  display: flex; flex-direction: column; gap: 1.3cqi;
  padding: 2cqi 2.2cqi;
  rotate: -3deg;
  background-color: var(--color-plan-paper);
  background-image:
    linear-gradient(var(--color-plan-grid) 0.08cqi, transparent 0.08cqi),
    linear-gradient(90deg, var(--color-plan-grid) 0.08cqi, transparent 0.08cqi);
  background-size: 1.6cqi 1.6cqi;
  color: var(--color-plan-graphite);
  font-style: italic;
}
.sk__title { align-self: flex-start; font-size: 1.7cqi; padding-block-end: 0.3cqi; border-block-end: 0.18cqi solid var(--color-plan-graphite); border-radius: 0 0 40% 10%; }
/* the client's needs, in their words; each one is a part of the built
   screen beside it (the job list, On site now, Due today) */
.sk__list { display: flex; flex-direction: column; gap: 0.9cqi; }
.sk__list em { font-size: 1.35cqi; font-style: italic; }
.sk__list em::before { content: "– "; }
/* the reason anyone asks for a platform, circled */
.sk__note {
  align-self: flex-start; margin-block-start: 0.4cqi; padding: 0.5cqi 1.1cqi;
  font-size: 1.2cqi; font-weight: 600;
  border: 0.18cqi solid var(--color-plan-graphite); border-radius: 48% 52% 45% 55% / 60% 45% 55% 40%;
  rotate: -2deg;
}
/* chalk on the wall: the sketch, pointing at what it became */
.plan__arrow {
  position: absolute; z-index: 1;
  inset-inline-start: 31cqi; inset-block-start: 31cqi; inline-size: 11cqi;
  fill: none; stroke: var(--color-plan-chalk); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
  transition: opacity 0.6s var(--ease-out) 0.3s;
}
.more.is-live .mcard:not(.is-active) .plan__arrow { opacity: 0; transition-delay: 0s; }

/* ---- the other rooms (2026-09-22), same rules as the spa: a place per card,
   drawn, no stock; dark where the text sits; % for position, cqi for size.
   Invoicing is left on the night surface until its copy is settled. ---- */

/* 1 · services — Sanad Advisory's office, a slate morning: a tall window
   behind vertical blinds, their stripes on the floor, an olive tree, a low
   oak cabinet with books and a lamp */
.scene--office {
  --floor: 74%;
  background:
    radial-gradient(ellipse 46cqi 32cqi at 76% 18%, var(--color-office-sun-haze), transparent 70%),
    linear-gradient(180deg, var(--color-office-wall-top) 0%, var(--color-office-wall) var(--floor),
      var(--color-office-floor) var(--floor), var(--color-office-floor-2) 100%);
}
.off__window {
  inset-inline-start: 64%; inset-block-start: 0;
  inline-size: 24cqi; block-size: var(--floor);
  background:
    repeating-linear-gradient(90deg, transparent 0 1.3cqi, var(--color-office-slat) 1.3cqi 1.6cqi),
    linear-gradient(180deg, var(--color-office-sky), var(--color-office-sun) 70%);
  box-shadow: inset 0 0 0 0.9cqi var(--color-office-frame), 0 0 12cqi 1cqi var(--color-office-sun-haze);
}
.off__stripes {
  inset-inline-start: 10%; inset-block-start: var(--floor);
  inline-size: 80cqi; block-size: calc(100% - var(--floor));
  clip-path: polygon(67% 0, 97% 0, 42% 100%, 0 100%);
  background:
    repeating-linear-gradient(62deg, transparent 0 1.3cqi, var(--color-office-floor) 1.3cqi 1.9cqi),
    linear-gradient(180deg, oklch(93% 0.04 85 / 0.40), oklch(93% 0.04 85 / 0.10));
  filter: blur(0.25cqi);
}
.off__credenza {
  inset-inline-start: 15%; inset-block-start: calc(var(--floor) - 5cqi);
  inline-size: 14cqi; block-size: 5cqi;
  background:
    repeating-linear-gradient(90deg, transparent 0 3.3cqi, var(--color-office-oak-2) 3.3cqi 3.5cqi),
    linear-gradient(180deg, var(--color-office-oak), var(--color-office-oak-2));
  box-shadow: 0 1.4cqi 1.6cqi -0.6cqi oklch(10% 0.01 60 / 0.7);
}
.off__books {
  position: absolute; inset-inline-start: 1.4cqi; inset-block-end: 100%;
  inline-size: 4.4cqi; block-size: 1.9cqi;
  background: linear-gradient(180deg, var(--color-office-pot) 0 33%, var(--color-office-leaf-2) 33% 66%, var(--color-office-oak-2) 66%);
}
.off__lamp {
  position: absolute; inset-inline-end: 2cqi; inset-block-end: 100%;
  inline-size: 3.4cqi; block-size: 4.6cqi;
}
.off__lamp::before {                    /* stem */
  content: ""; position: absolute; inset-inline-start: calc(50% - 0.12cqi); inset-block-end: 0;
  inline-size: 0.24cqi; block-size: 2.6cqi; background: var(--color-office-frame);
}
.off__lamp::after {                     /* shade, lit */
  content: ""; position: absolute; inset-inline: 0; inset-block-start: 0; block-size: 2.2cqi;
  clip-path: polygon(22% 0, 78% 0, 100% 100%, 0 100%);
  background: linear-gradient(180deg, var(--color-office-pot), var(--color-office-lamp));
}
.off__lamp { filter: drop-shadow(0 1cqi 2cqi oklch(86% 0.10 78 / 0.55)); }
.off__tree {
  inset-inline-start: 3%; inset-block-start: calc(var(--floor) - 4.5cqi);
  inline-size: 5.5cqi; block-size: 4.5cqi;
  border-radius: 0.3cqi 0.3cqi 1cqi 1cqi;
  background: linear-gradient(90deg, var(--color-office-pot), oklch(58% 0.012 80));
  box-shadow: 0 1.2cqi 1.4cqi -0.6cqi oklch(10% 0.01 60 / 0.7);
}
.off__tree::before {                    /* trunk */
  content: ""; position: absolute; inset-inline-start: 45%; inset-block-end: 100%;
  inline-size: 0.5cqi; block-size: 13cqi; background: var(--color-office-oak-2);
  transform: rotate(-4deg); transform-origin: bottom;
}
.off__tree i {                          /* the canopy, in clumps */
  position: absolute; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, var(--color-office-leaf), var(--color-office-leaf-2) 70%);
  box-shadow: inset -0.6cqi -0.6cqi 1.2cqi oklch(15% 0.03 150 / 0.5);
}
.off__tree i:nth-child(1) { inline-size: 9cqi;  block-size: 6cqi; inset-block-end: 13cqi; inset-inline-start: -2cqi; }
.off__tree i:nth-child(2) { inline-size: 7cqi;  block-size: 5cqi; inset-block-end: 17cqi; inset-inline-start: 2cqi; }
.off__tree i:nth-child(3) { inline-size: 6cqi;  block-size: 4.5cqi; inset-block-end: 11.5cqi; inset-inline-start: 3.5cqi; }
.off__tree i:nth-child(4) { inline-size: 5cqi;  block-size: 4cqi; inset-block-end: 16cqi; inset-inline-start: -2.5cqi; }
.off__tree i:nth-child(5) { inline-size: 4cqi;  block-size: 3.2cqi; inset-block-end: 20.5cqi; inset-inline-start: 0.5cqi; }

/* 2 · store — Qamra Coffee's bar: fluted oak, three brass pendants, a shelf
   of jars and bags, the counter with a cup still steaming */
.scene--cafe {
  --counter: 71%;
  background:
    radial-gradient(ellipse 52cqi 26cqi at 68% 14%, var(--color-cafe-lamp-haze), transparent 70%),
    repeating-linear-gradient(90deg, var(--color-cafe-flute) 0 0.25cqi, transparent 0.25cqi 1.7cqi),
    linear-gradient(180deg, var(--color-cafe-wall-top), var(--color-cafe-wall) 72%, var(--color-cafe-wall-top));
}
.cafe__shelf {
  inset-inline-start: 50%; inset-block-start: 22%;
  inline-size: 48cqi; block-size: 6.6cqi;
  display: flex; align-items: flex-end; gap: 2.2cqi; padding-inline: 4cqi;
  border-block-end: 0.8cqi solid var(--color-cafe-oak);
  box-shadow: 0 1.6cqi 1.4cqi -1cqi oklch(8% 0.02 50 / 0.7);
}
.cafe__jar {
  flex: none; inline-size: 3.2cqi; block-size: 4.8cqi; border-radius: 0.5cqi 0.5cqi 0.3cqi 0.3cqi;
  background:
    linear-gradient(180deg, var(--color-cafe-brass) 0 0.7cqi, transparent 0.7cqi),
    linear-gradient(0deg, var(--color-cafe-bean) 0 62%, transparent 62%),
    var(--color-cafe-glass);
  box-shadow: inset 0.4cqi 0 0.3cqi oklch(100% 0 0 / 0.12);
}
.cafe__bag {
  flex: none; inline-size: 3.6cqi; block-size: 5.6cqi; border-radius: 0.4cqi 0.4cqi 0.2cqi 0.2cqi;
  background:
    linear-gradient(180deg, transparent 42%, var(--color-cafe-oak) 42% 60%, transparent 60%) center / 64% 100% no-repeat,
    linear-gradient(100deg, var(--color-cafe-oak-2), var(--color-cafe-bag) 55%);
}
.cafe__pendant { inset-block-start: 0; inline-size: 5.4cqi; }
/* they hang clear of the shelf's jars, so nothing reads as stacked */
.cafe__pendant:nth-child(2) { inset-inline-start: 54%; block-size: 7cqi; }
.cafe__pendant:nth-child(3) { inset-inline-start: 67%; block-size: 10cqi; }
.cafe__pendant:nth-child(4) { inset-inline-start: 80%; block-size: 8cqi; }
.cafe__pendant::before {                /* the cord */
  content: ""; position: absolute; inset-inline-start: calc(50% - 0.08cqi); inset-block: 0 2.4cqi;
  inline-size: 0.16cqi; background: var(--color-cafe-brass-2);
}
.cafe__pendant::after {                 /* the dome, lit from under */
  content: ""; position: absolute; inset-inline: 0; inset-block-end: 0; block-size: 2.6cqi;
  border-radius: 2.7cqi 2.7cqi 0 0 / 2.6cqi 2.6cqi 0 0;
  background: linear-gradient(180deg, var(--color-cafe-brass), var(--color-cafe-brass-2));
  border-block-end: 0.45cqi solid var(--color-cafe-lamp);
  box-shadow: 0 2.2cqi 5cqi 0.4cqi var(--color-cafe-lamp-haze);
}
.cafe__counter {
  inset-inline-start: 0; inset-block-start: var(--counter); inset-block-end: 0;
  inline-size: 34cqi;
  border-block-start: 1.3cqi solid var(--color-cafe-oak);
  background:
    repeating-linear-gradient(90deg, oklch(8% 0.02 50 / 0.35) 0 0.3cqi, transparent 0.3cqi 1.5cqi),
    linear-gradient(180deg, var(--color-cafe-oak-2), var(--color-cafe-wall-top));
  box-shadow: 0 -0.2cqi 0 var(--color-cafe-lamp-haze);
}
.cafe__cup {
  position: absolute; inset-inline-start: 7cqi; inset-block-end: calc(100% + 1.3cqi);
  inline-size: 3.4cqi; block-size: 2.6cqi; border-radius: 0.2cqi 0.2cqi 1.5cqi 1.5cqi;
  background: linear-gradient(90deg, var(--color-cafe-cup), oklch(80% 0.012 80));
}
.cafe__cup::before {                    /* handle */
  content: ""; position: absolute; inset-inline-start: 88%; inset-block-start: 0.4cqi;
  inline-size: 1.2cqi; block-size: 1.2cqi; border-radius: 50%;
  border: 0.3cqi solid var(--color-cafe-cup);
}
.cafe__cup::after {                     /* saucer */
  content: ""; position: absolute; inset-inline: -1.2cqi; inset-block-end: -0.5cqi; block-size: 0.6cqi;
  border-radius: 50%; background: var(--color-cafe-cup);
}
.cafe__grinder {
  position: absolute; inset-inline-start: 19cqi; inset-block-end: calc(100% + 1.3cqi);
  inline-size: 3.6cqi; block-size: 5cqi; border-radius: 0.4cqi;
  background: linear-gradient(90deg, var(--color-cafe-bag), oklch(40% 0.02 55) 45%, var(--color-cafe-bag));
}
.cafe__grinder::before {                /* the hopper */
  content: ""; position: absolute; inset-inline: -0.6cqi; inset-block-end: 100%; block-size: 3cqi;
  clip-path: polygon(0 0, 100% 0, 70% 100%, 30% 100%);
  background: linear-gradient(0deg, var(--color-cafe-bean) 0 55%, var(--color-cafe-glass) 55%);
}
.cafe__cup .steam { inset-inline-start: 50%; }

/* the Saudi checkout: the methods a Saudi buyer looks for, set as type in the
   brands' colours (not their logo files). Squarespace floats the same kind of
   panel over its store card. */
/* compact enough to clear the page's Add to cart above it */
.fl--pay { inset-inline-end: 2.5cqi; inset-block-end: 1.2cqi; inline-size: 27cqi; padding: 1.4cqi; }
.fl--pay .fl__k { margin-block-end: 0.9cqi; }
.pay { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.5cqi; }
.pm {
  display: flex; align-items: center; justify-content: center; gap: 0.4cqi;
  block-size: 2.8cqi; border-radius: var(--radius-xs);
  background: var(--color-paper); box-shadow: inset 0 0 0 1px var(--color-rule);
  font-family: var(--font-body); font-weight: 700; font-size: 1.05cqi; letter-spacing: -0.01em; white-space: nowrap;
}
.pm--apple  { background: var(--color-pay-apple); color: var(--color-paper); box-shadow: none; font-weight: 600; font-size: 0.95cqi; letter-spacing: -0.02em; }
.pm--mada   { color: var(--color-pay-mada-1); text-transform: lowercase; }
.pm--mada i { inline-size: 1cqi; block-size: 1cqi; background: linear-gradient(180deg, var(--color-pay-mada-1) 0 45%, transparent 45% 55%, var(--color-pay-mada-2) 55%); }
.pm--visa   { color: var(--color-pay-visa); font-style: italic; font-weight: 800; font-size: 1.25cqi; letter-spacing: 0.02em; }
.pm--mc i   { inline-size: 1.7cqi; aspect-ratio: 1; border-radius: 50%; background: var(--color-pay-mc-1); }
.pm--mc i + i { background: var(--color-pay-mc-2); margin-inline-start: -0.8cqi; mix-blend-mode: multiply; }
.pm--stc    { grid-column: span 2; background: var(--color-pay-stc); color: var(--color-paper); box-shadow: none; }
.pm--tabby  { background: var(--color-pay-tabby); color: var(--color-pay-apple); box-shadow: none; }
.pm--tamara { background: linear-gradient(100deg, var(--color-pay-tamara-1), var(--color-pay-tamara-2) 55%, var(--color-pay-tamara-3)); color: var(--color-pay-apple); box-shadow: none; }

/* 4 · apps — Riyadh at dusk: the skyline with its lit windows and the
   tower's opening, date palms, a lamp, a quiet street */
.scene--dusk {
  --horizon: 62%;
  background: linear-gradient(180deg,
    var(--color-dusk-sky-top) 0%, var(--color-dusk-sky) 36%, var(--color-dusk-glow) calc(var(--horizon) - 6%),
    var(--color-dusk-horizon) var(--horizon), var(--color-dusk-road) var(--horizon), var(--color-dusk-road-2) 100%);
}
.dusk__city {
  inset-inline: 0; inset-block-end: calc(100% - var(--horizon));
  display: flex; align-items: flex-end; justify-content: space-between; padding-inline: 1cqi;
}
.dusk__city i {
  flex: none;
  background:
    radial-gradient(circle, var(--color-dusk-window) 0.15cqi, transparent 0.26cqi) 0.4cqi 0.6cqi / 1.3cqi 1.8cqi,
    var(--color-dusk-city);
}
.dusk__city i:nth-child(1)  { inline-size: 8cqi;  block-size: 10cqi; }
.dusk__city i:nth-child(2)  { inline-size: 6cqi;  block-size: 15cqi; background: var(--color-dusk-city); }
.dusk__city i:nth-child(4)  { inline-size: 10cqi; block-size: 12cqi; }
.dusk__city i:nth-child(5)  { inline-size: 7cqi;  block-size: 18cqi; }
.dusk__city i:nth-child(6)  { inline-size: 11cqi; block-size: 8cqi; background: var(--color-dusk-city); }
.dusk__city i:nth-child(7)  { inline-size: 6cqi;  block-size: 21cqi; }
.dusk__city i:nth-child(8)  { inline-size: 12cqi; block-size: 11cqi; }
.dusk__city i:nth-child(9)  { inline-size: 9cqi;  block-size: 15cqi; background: var(--color-dusk-city); }
.dusk__city i:nth-child(10) { inline-size: 10cqi; block-size: 9cqi; }
.dusk__city i.dusk__tower {             /* tapering, with the opening near the top */
  inline-size: 6cqi; block-size: 21cqi;
  background: linear-gradient(90deg, var(--color-dusk-city) 50%, oklch(22% 0.025 265));
  clip-path: polygon(22% 0, 78% 0, 100% 100%, 0 100%);
  -webkit-mask: radial-gradient(ellipse 30% 10% at 50% 9%, transparent 96%, #000 100%);
          mask: radial-gradient(ellipse 30% 10% at 50% 9%, transparent 96%, #000 100%);
}
.dusk__road {
  inset-inline: 0; inset-block-start: var(--horizon); block-size: 0.5cqi;
  background: oklch(74% 0.11 62 / 0.35); filter: blur(0.2cqi);
}
/* a quiet evening street, not a motorway (2026-09-26): the tail-light
   streaks read as traffic, the delivery feel the owner took out. Now a
   pavement edge and the warm light of a café off to the right. */
/* the pavement the palms and the lamp stand on: lit near the skyline,
   ending in a kerb line, so their feet land on something */
.dusk__kerb {
  inset-inline: 0; inset-block-start: var(--horizon); block-size: 11%;
  background: linear-gradient(180deg, var(--color-dusk-kerb), var(--color-dusk-pave) 92%, var(--color-dusk-kerb-edge) 92% 96%, transparent 96%);
}
.dusk__spill {                     /* where the light falls: under the lamp and the palms, left of the phones */
  inset-inline-start: 0; inset-block-start: var(--horizon); inline-size: 70cqi; block-size: 38%;
  background: radial-gradient(ellipse 55% 70% at 38% 0%, var(--color-dusk-spill), transparent 78%);
}
.dusk__palm {
  inset-inline-start: 6%; inset-block-start: calc(var(--horizon) + 8% - 16cqi);
  inline-size: 0.9cqi; block-size: 16cqi;
  background: repeating-linear-gradient(0deg, var(--color-dusk-palm) 0 0.6cqi, oklch(16% 0.015 220) 0.6cqi 0.8cqi);
  transform: rotate(3deg); transform-origin: bottom;
}
.dusk__palm--2 { inset-inline-start: 17%; block-size: 12cqi; inset-block-start: calc(var(--horizon) + 6% - 12cqi); transform: rotate(-4deg); }
.dusk__palm i {
  position: absolute; inset-block-start: 0; inset-inline-start: 50%;
  inline-size: 8cqi; block-size: 1.3cqi; margin-block-start: -0.65cqi;
  background: var(--color-dusk-palm);
  border-radius: 0 100% 0 100% / 0 100% 0 100%;
  transform-origin: 0 50%;
}
.dusk__palm--2 i { inline-size: 6.5cqi; }
.dusk__palm i:nth-child(1) { transform: rotate(-165deg); }
.dusk__palm i:nth-child(2) { transform: rotate(-135deg); }
.dusk__palm i:nth-child(3) { transform: rotate(-105deg) scaleX(0.8); }
.dusk__palm i:nth-child(4) { transform: rotate(-70deg) scaleX(0.85); }
.dusk__palm i:nth-child(5) { transform: rotate(-40deg); }
.dusk__palm i:nth-child(6) { transform: rotate(-10deg); }
.dusk__palm i:nth-child(7) { transform: rotate(25deg) scaleX(0.9); }
.dusk__lamp {
  inset-inline-start: 28%; inset-block-start: calc(var(--horizon) + 10% - 18cqi);
  inline-size: 0.35cqi; block-size: 18cqi; background: var(--color-dusk-city);
}
.dusk__lamp::after {
  content: ""; position: absolute; inset-inline-start: -0.6cqi; inset-block-start: -0.4cqi;
  inline-size: 1.6cqi; block-size: 0.8cqi; border-radius: 50%;
  background: var(--color-dusk-head); box-shadow: 0 0 3cqi 1.2cqi oklch(88% 0.10 80 / 0.45);
}

/* 6 · platforms — a planning room after hours: an olive wall with the
   week's sticky notes, a birch table the sketch lies on, a pencil beside it */
.scene--plan {
  --floor: 84%;
  background: linear-gradient(180deg, var(--color-plan-wall-top) 0%, var(--color-plan-wall) var(--floor),
    var(--color-plan-table) var(--floor), var(--color-plan-table-2) 100%);
}
.plan__notes { inset-inline-start: 50%; inset-block-start: 4%; display: flex; gap: 2.2cqi; }
.plan__notes i {
  inline-size: 5cqi; aspect-ratio: 1;
  background:
    linear-gradient(var(--color-plan-marker) 0 0) 20% 32% / 60% 0.25cqi no-repeat,
    linear-gradient(var(--color-plan-marker) 0 0) 20% 52% / 45% 0.25cqi no-repeat,
    var(--color-plan-note);
  box-shadow: 0 0.6cqi 1cqi -0.4cqi oklch(10% 0.02 120 / 0.6);
  rotate: -4deg;
}
.plan__notes i:nth-child(2) { background-color: var(--color-plan-note-2); rotate: 3deg; margin-block-start: 1cqi; }
.plan__notes i:nth-child(3) { rotate: -1deg; }
.plan__notes i:nth-child(4) { background-color: var(--color-plan-note-3); rotate: 5deg; margin-block-start: 0.6cqi; }
.plan__notes i:nth-child(5) { background-color: var(--color-plan-note-2); rotate: -3deg; }
.plan__pencil {
  inset-inline-start: 34%; inset-block-start: calc(var(--floor) + 5%);
  inline-size: 9cqi; block-size: 0.8cqi;
  background: linear-gradient(90deg, var(--color-plan-graphite) 0 5%, var(--color-plan-wood) 5% 14%, var(--color-plan-pencil) 14% 94%, var(--color-plan-eraser) 94%);
  clip-path: polygon(0 50%, 14% 0, 100% 0, 100% 100%, 14% 100%);
  rotate: 12deg;
}

/* ---- JS-driven glide: the track moves by transform on the measured curve.
   The browser's own smooth scroll can't be timed or eased, so with JS the
   viewport stops scrolling natively and the track slides instead. ---- */
.more.is-live .more__viewport { overflow: hidden; scroll-snap-type: none; touch-action: pan-y; }
.more.is-live .more__track {
  transform: translate3d(var(--tx, 0px), 0, 0);
  transition: transform var(--dur-glide) var(--ease-glide);
}
.more.is-live .more__track.is-jump { transition: none; }
.more.is-live .more__viewport.is-dragging { cursor: grabbing; }

/* ---- the peek label: Squarespace's cursor-follow, measured 2026-09-22.
   Over a neighbouring card a label trails the pointer on a soft spring (JS,
   ~300ms to settle) and says where a click goes: Next or Previous. It pops
   in from 75%. Theirs is a white pill; ours is paper with our 2px corners and
   the nav's caps, so it reads as the page's own control over the night card.
   Mouse only: touch has no pointer to follow, and the peeks still work. ---- */
.more__cursor {
  position: fixed; inset: 0 auto auto 0; z-index: 30; pointer-events: none;
  transform: translate3d(var(--cx, 0px), var(--cy, 0px), 0);
}
.more__cursor[hidden] { display: none; }
.more__cursor-label {
  display: block; padding: 0.7rem 1rem;
  background: var(--color-paper); color: var(--color-ink); border-radius: var(--radius-xs);
  box-shadow: var(--shadow-float);
  font-size: var(--text-nav); font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap;
  opacity: 0; transform: scale(0.75); transform-origin: 0 0;
  transition: opacity var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out);
}
.more__cursor.is-on .more__cursor-label { opacity: 1; transform: none; }

/* ---- controls: the indicator in the middle, the pause at the right edge of
   the card column (Squarespace puts it at the section's edge, apart). ---- */
.more__controls {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  inline-size: var(--card-w); margin: var(--space-lg) auto 0;
}
.more__controls[hidden] { display: none; }
/* The indicator, on Squarespace's model: the active position is a 32×6 bar
   that fills over the dwell — you can see when it will move — its neighbours
   5px, the rest 4px, and the bar grows and shrinks between positions. */
.more__dots { grid-column: 2; display: flex; align-items: center; gap: 8px; }
.more__dots i {
  position: relative; overflow: hidden;
  inline-size: 4px; block-size: 4px; border-radius: var(--radius-sm);
  background: var(--color-neutral);
  transition: inline-size 0.5s var(--ease-glide), block-size 0.5s var(--ease-glide);
}
.more__dots i.is-near { inline-size: 5px; block-size: 5px; }
.more__dots i.is-on   { inline-size: 32px; block-size: 6px; }
.more__dots i::after {
  content: ""; position: absolute; inset: 0; background: var(--color-ink);
  transform: scaleX(0); transform-origin: left center;
}
.more__dots i.is-on::after { transform: scaleX(1); }
.more.is-playing .more__dots i.is-on::after { animation: dot-fill var(--dwell, 5s) linear forwards; }
@keyframes dot-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.more__pause {
  grid-column: 3; justify-self: end;
  inline-size: 40px; block-size: 40px; display: grid; place-items: center;
  border: var(--rule-hair) solid var(--color-rule); border-radius: 50%; background: none; cursor: pointer; color: var(--color-ink);
}
.more__pause:hover { border-color: var(--color-ink); }
.more__pause:focus-visible { outline: var(--rule-bold) solid var(--color-focus); outline-offset: 2px; }
/* pause glyph: two bars; when paused (aria-pressed=true) it becomes a play triangle */
.more__pause-ico { inline-size: 10px; block-size: 12px; border-inline: 3px solid currentColor; box-sizing: border-box; }
.more__pause[aria-pressed="true"] .more__pause-ico { inline-size: 0; block-size: 0; border: 0; border-block: 6px solid transparent; border-inline-start: 10px solid currentColor; margin-inline-start: 3px; }

/* narrow: taller cards, text above the drawing, the drawing larger */
@media (max-width: 48rem) {
  .more { --card-w: 86vw; }
  .more__tabs { gap: var(--space-2xs); }
  .more__tab { font-size: var(--text-sm); }
  .mcard { aspect-ratio: 4 / 5; }
  .mcard__text { max-inline-size: 88%; inset-inline-start: 6%; inset-block-start: 6%; }
  /* platforms in the tall card (tablet): place the pieces by the card's
     height so the sketch still lies against the screen it became. The
     phone rules further down take over under 40rem. */
  .plan__notes { inset-block-start: 25%; }
  .mk--plat { inset-block-start: 43%; }
  .fl--sketch { inset-block-end: auto; inset-block-start: 65%; }
  .plan__arrow { display: none; }
  /* AI agents in the tall card: the chat and its notification start below
     the full-width text (the chat used to cover the Great for line) */
  .iph.iph--chat { inset-block-start: 30%; }
  .fl--hand { inset-block-start: 60%; }
  /* Invoicing in the tall card: the ERP and the invoice start below the
     full-width text, the invoice still in front of the ERP's lower left */
  .mk--erp { inset-block-start: 30%; }
  .mk--inv { inset-block-start: 58%; }
  .fl--zatca { inset-block-start: calc(58% - 3cqi); }
  /* Apps in the tall card: both phones start below the full-width text */
  .iph--order { inset-block-start: 26%; }
  .fl--push { inset-block-start: calc(26% + 4cqi); }
  .iph--menu  { inset-block-start: 32%; }
}

/* Phones, on Squarespace's mobile model (owner, 2026-09-28): one card, whole.
   The desktop peeks of the neighbours become two cut-off
   slivers at 375 that read as clutter; the tabs, the dots and the autoplay
   already say there is more. The sub drops to body size so it sits on one line under the
   two-line heading (Squarespace: short heading, one-line sub). */
@media (max-width: 40rem) {
  /* Full bleed, as Squarespace's phone cards (owner, 2026-09-28): edge to
     edge, square, no gap; the text starts on the page gutter so it lines up
     with the heading column; the controls stay on the text column. */
  .more { --card-w: 100vw; }
  .more__track { gap: 0; }
  .mcard { border-radius: 0; }
  .mcard__text { inset-inline-start: var(--page-gutter); max-inline-size: calc(100% - 2 * var(--page-gutter)); }
  .more__controls { inline-size: calc(100vw - 2 * var(--page-gutter)); }
  .more__sub { font-size: var(--text-base); }
  /* the pause read huge beside the 4px dots (owner): a 32px circle, as on
     Squarespace's phone page; the ::before keeps a 44px tap area */
  .more__pause { inline-size: 32px; block-size: 32px; position: relative; }
  /* at the left end of the row on phones (owner, 2026-09-30): at the right
     it sat under the fixed WhatsApp button */
  .more__pause { grid-column: 1; grid-row: 1; justify-self: start; }
  .more__pause::before { content: ""; position: absolute; inset: -6px; }
  .more__pause-ico { inline-size: 8px; block-size: 10px; border-inline-width: 2.5px; }
  .more__pause[aria-pressed="true"] .more__pause-ico { border-block-width: 5px; border-inline-start-width: 8px; margin-inline-start: 2px; }
  /* The tab strip as Squarespace's (owner, 2026-09-28): full bleed, larger
     names, about three in view with the active one centred and slivers of
     its neighbours' neighbours at the screen edges (app.js centres the active
     tab). At the ends it stops, as Squarespace's does: the first pill starts
     on the gutter with no sliver to its left, the last ends on the gutter. */
  .more__tabs {
    margin-inline: calc(50% - 50vw); padding-inline: var(--page-gutter);
    gap: 0;
  }
  .more__tab { font-size: 1.0625rem; padding-inline: 0.9rem; }   /* 3 whole pills + slivers at 375; larger filled the width and hid the slivers */
}

@container (max-width: 40rem) {
  .mk { inline-size: 104cqi; inset-inline-end: -10cqi; inset-block-end: -8cqi; padding: 3.5cqi 4cqi; }
  .mk__brand { font-size: 3cqi; } .mk__pill { font-size: 1.9cqi; } .mk__h { font-size: 5cqi; }
  .mk__kicker, .fl__k, .svc em, .inv__title b { font-size: 1.7cqi; }
  .mk__btn, .mk__opts em, .svc, .fl, .fl__cta, .inv__meta, .inv__row, .inv__sums { font-size: 2cqi; }
  .fl { padding: 3.4cqi; }
  .fl--cart, .fl--slots { inset-inline-start: 5cqi; inset-block-end: 6cqi; inline-size: 50cqi; }
  .fl--chip { inset-block-start: auto; inset-block-end: 50cqi; inset-inline-end: 5cqi; }
  .mk--inv { inline-size: 70cqi; inset-inline-end: -4cqi; }
  .inv__row { grid-template-columns: 1fr 6cqi 16cqi; } .inv__total { font-size: 3.6cqi; }
  /* Darb: the order phone leads, the menu tucks behind it, the banner
     sits low (the text runs the full width up top) */
  .iph--order { --w: 46cqi; inset-inline-end: auto; inset-inline-start: 8cqi; inset-block-start: 40cqi; }
  .iph--menu  { --w: 40cqi; inset-inline-end: 3cqi; inset-block-start: 50cqi; }
  .fl--push { inset-inline-start: 5cqi; inset-block-start: auto; inset-block-end: 3cqi; inline-size: 64cqi; gap: 2.4cqi; padding: 2.4cqi 2.8cqi; border-radius: 4.4cqi; font-size: 2cqi; }
  .push__icon { inline-size: 7cqi; border-radius: 1.8cqi; } .push__icon::after { border-width: 0.7cqi; }
  .push__top { font-size: 1.7cqi; }
  .mk--svcs { inset-block-start: auto; inset-block-end: -8cqi; }
  .mk__hero { block-size: 30cqi; padding-inline-end: 10cqi; } /* the window overhangs the card by 10cqi */
  .mk__hero-h { font-size: 4.2cqi; max-inline-size: 34cqi; }
  .tile em, .fld em { font-size: 1.6cqi; } .tile__h { font-size: 2.2cqi; }
  .fl--enq { inset-inline-start: 5cqi; inset-inline-end: auto; inset-block-start: auto; inset-block-end: 6cqi; inline-size: 50cqi; }
  .fld i, .fld--sel span { block-size: 5cqi; } .fld--sel span { padding-inline: 2cqi; }
  /* the spa: the text runs the full width up top, so the arch drops below it
     and grows, and the room's back wall starts lower */
  .scene--spa { --floor: 62%; }
  .spa__arch { inset-inline-start: 58%; inset-block-start: 36%; inline-size: 24cqi; border-radius: 12cqi 12cqi 0 0; }
  .spa__glint { inset-inline-start: 55%; inline-size: 30cqi; }
  .spa__bed { inline-size: 42cqi; }
  /* the other rooms, measured at 375: each gets the band between the end of
     the text and the top of its interface, and nothing bright sits behind text */
  .scene--office { --floor: 57%; }
  .off__window { inset-inline-start: 60%; inset-block-start: 37%; inline-size: 30cqi; block-size: calc(var(--floor) - 37%); }
  .off__credenza { inset-inline-start: 24%; inline-size: 20cqi; }
  .cafe__pendant { display: none; }                  /* their cords would cross the text */
  .cafe__shelf { inset-inline-start: 4%; inset-block-start: 30%; inline-size: 92cqi; justify-content: space-around; }
  .scene--cafe { background-position: 0 0; }
  .fl--pay { inset-inline-start: auto; inset-inline-end: 4cqi; inset-block-end: 14cqi; inline-size: 42cqi; padding: 3cqi; }   /* above the Sample tag, clear of the cart */
  .fl--pay .fl__k { margin-block-end: 1.6cqi; }
  .pay { gap: 1cqi; }
  .pm { block-size: 5.4cqi; font-size: 1.9cqi; }
  .pm--apple { font-size: 1.7cqi; } .pm--visa { font-size: 2.2cqi; }
  .pm--mada i { inline-size: 1.8cqi; block-size: 1.8cqi; } .pm--mc i { inline-size: 3cqi; } .pm--mc i + i { margin-inline-start: -1.4cqi; }
  /* AI agents: the chat leads under the text, the hand-over chip rides its
     edge, the behind-the-scenes panel sits above the Sample tag; the sign
     would hide behind the phone, so it goes */
  .scene--night { --floor: 86%; }
  .night__window { inline-size: 30cqi; inset-block-start: 44%; }
  .night__plant { display: none; }
  .iph.iph--chat { --w: 58cqi; inset-inline-end: auto; inset-inline-start: 6cqi; inset-block-start: 53cqi; }
  .fl--hand { inset-inline-end: 4cqi; inset-block-start: 56cqi; inline-size: 40cqi; gap: 2cqi; padding: 2cqi 2.4cqi; border-radius: 3.6cqi; font-size: 1.9cqi; }
  .hand__face { inline-size: 6.4cqi; border-radius: 1.6cqi; font-size: 2.6cqi; }
  .fl--hand .push__top { font-size: 1.6cqi; }
  .fl--flow { display: none; }   /* three layers is one too many here; the notification names every agent's night */

  /* invoice to ERP: the text runs to ~45% here, so the invoice starts below
     it and keeps only what proves the point — the bilingual head, one line,
     the QR and the total. The module rail goes: the text already names the
     modules, and there is no room left to show them. */
  /* the ERP upper right under the text (its sidebar, the title and the four
     figures), the trimmed invoice in front of its lower left, the ZATCA
     chip on the invoice's corner */
  .mk--erp { inline-size: 72cqi; inset-inline-start: auto; inset-inline-end: -6cqi; inset-block-start: 60cqi; inset-block-end: auto; padding: 0; grid-template-columns: 22cqi minmax(0, 1fr); }
  .erp__side { font-size: 1.9cqi; padding: 3cqi 2cqi; gap: 0.8cqi; }
  .erp__brand { font-size: 2.1cqi; gap: 1.2cqi; margin-block-end: 2cqi; } .erp__mark { inline-size: 3.6cqi; font-size: 2cqi; }
  .erp__side em { padding: 1cqi 1.2cqi; }
  .erp__main { padding: 3cqi; gap: 2cqi; }
  .erp__bar, .erp__tabs, .erp__k, .erp__chart { display: none !important; }
  .erp__head b { font-size: 3cqi; }
  .erp__kpis { gap: 1.6cqi; margin-block-start: 0; } .erp__kpis > span { padding: 1.8cqi; }
  .erp__kpis em { font-size: 1.4cqi; } .erp__kpis b { font-size: 3.2cqi; } .erp__up { font-size: 1.5cqi; inset-block-start: 1.8cqi; inset-inline-end: 1.8cqi; }
  .mk--inv { inline-size: 62cqi; inset-inline-start: 4cqi; inset-inline-end: auto; inset-block-start: 86cqi; inset-block-end: auto; padding: 3.4cqi 4cqi; }
  .inv { gap: 2cqi; }
  .inv > :nth-child(2), .inv > :nth-child(3), .inv > :nth-child(5) { display: none; }
  .inv__row { grid-template-columns: 1fr 6cqi 16cqi; }
  .inv__title b[lang] { font-size: 2.6cqi; }
  .inv__sums em { font-size: 1.5cqi; }
  .mk--inv .qr { inline-size: 14cqi; }
  .fl--zatca { inset-inline-start: 6cqi; inset-inline-end: auto; inset-block-start: 81cqi; gap: 1.6cqi; padding: 1.8cqi 2.8cqi; font-size: 2.1cqi; }
  .fl--zatca .zt__tick { inline-size: 2.8cqi; }          /* only a 4% band shows here; the wall carries it */
  /* platforms, measured at 375: the text runs the full width up top, so the
     built screen takes the upper right under it (its name and figures stay
     in view) and the sketch lies over the lower left of its job list. The
     screen loses its sidebar and the District column; the notes, arrow and
     pencil go (the notes would sit behind the text). */
  .plan__notes, .plan__arrow, .plan__pencil { display: none; }
  .mk--plat { inline-size: 74cqi; inset-inline-end: -6cqi; inset-block-start: 52cqi; inset-block-end: auto; }
  .plat { grid-template-columns: minmax(0, 1fr); padding-block-start: 2.6cqi; }
  .plat__side, .plat__search { display: none; }
  .plat__kpis { gap: 1.6cqi; } .plat__kpis > span { padding: 1.6cqi; }
  .plat__kpis em, .plat__row--head { font-size: 1.4cqi; } .plat__kpis b { font-size: 4.4cqi; }
  .plat__row { font-size: 2cqi; grid-template-columns: minmax(0, 1fr) 13cqi; padding-block: 1.6cqi; }
  .plat__row > span:nth-child(2) { display: none; }
  .st { font-size: 1.7cqi; }
  .fl.fl--sketch { inset-inline-start: 4cqi; inset-block-end: auto; inset-block-start: 82cqi; inline-size: 44cqi; gap: 2cqi; padding: 3cqi 3.2cqi; background-size: 2.8cqi 2.8cqi; }
  .sk__title { font-size: 2.9cqi; } .sk__list { gap: 1.4cqi; } .sk__list em { font-size: 2.3cqi; } .sk__note { font-size: 2.1cqi; padding: 0.9cqi 1.8cqi; }
}
/* the narrowest phones (320): the text runs to about half the card, so the
   drawings start lower (platforms: the screen, and the sketch shrinks to
   stay inside the card; AI agents: the chat and its notification) */
@container (max-width: 19rem) {
  .mk--plat { inset-block-start: 71cqi; }
  .fl.fl--sketch { inset-block-start: 90cqi; inline-size: 43cqi; gap: 1.3cqi; padding: 2.4cqi 2.6cqi; }
  .sk__note { white-space: nowrap; font-size: 1.9cqi; padding: 0.7cqi 1.4cqi; }
  /* AI agents: the text runs to ~63% of the width here, so the chat and the
     morning notification start below it (they overlapped it before) */
  .iph.iph--chat { inset-block-start: 66cqi; }
  .fl--hand { inset-block-start: 68cqi; }
  /* Invoicing: the same, for the ERP, the invoice and its chip */
  .mk--erp { inset-block-start: 68cqi; }
  .mk--inv { inset-block-start: 86cqi; inline-size: 60cqi; }
  .mk--inv .qr { inline-size: 11cqi; }
  .fl--zatca { inset-block-start: 81cqi; }
  /* Apps: the same, for the order phone and the menu behind it */
  .iph--order { inset-block-start: 60cqi; }
  .iph--menu  { inset-block-start: 68cqi; }
}

@media (prefers-reduced-motion: reduce) {
  .more__ink, .fl, .more__dots i, .more__cursor-label { transition: none; }
  .more.is-live .more__track { transition: transform 0.2s linear; }
  .more.is-live .mcard:not(.is-active) .fl { opacity: 1; transform: none; }
}

/* ============================================================ F4 · process */

/* ONE story, four steps, each drawing always visible (2026-09-26, owner's
   call). The switch, steps-as-tabs and the autoplaying stage are gone; see the
   index.html note. What stays from the earlier versions, and must keep
   holding: WIDTH CARRIES ONE BIT. The three moments are equal columns, the
   fortnight is one wider column, and its band is ONE continuous bar divided
   only at day 7 (ink for the rebuild, vermilion for the refine, because
   refinement is the correction pass). Don't size columns to fit copy — trim
   the copy. Every step has the same mark row, so the titles and pictures line
   up: a rule for a moment, the labelled band for the fortnight. Rows are a
   subgrid, so a two-line title never pushes one picture below its neighbours. */
.track {
  display: grid;
  grid-template-columns: 1fr 1fr 2.3fr 1fr;
  column-gap: var(--space-lg); row-gap: var(--space-xs);
  margin: var(--space-xl) 0 0; padding: 0; list-style: none;
}
.tstep {
  display: grid; grid-row: span 4; grid-template-rows: subgrid;
  row-gap: var(--space-xs); min-inline-size: 0;
}
.tstep__mark { block-size: 1.5rem; margin: 0; display: flex; align-items: flex-end; }
/* a light grey hairline, not the bold ink rule: five heavy black bars in a
   row pulled the eye off the steps (owner, 2026-09-28). The 7 | 7 band on
   step 03 stays solid; it is the one mark here that carries information. */
.tstep__mark:empty::before { content: ""; flex: 1; block-size: 1px; background: var(--color-rule); }
.tband { align-items: stretch; }
.tband span:first-child { border-start-start-radius: var(--radius-sm); border-end-start-radius: var(--radius-sm); }
.tband span:last-child { border-start-end-radius: var(--radius-sm); border-end-end-radius: var(--radius-sm); }
.tband span {
  flex: 1 1 0; min-inline-size: 0; display: flex; align-items: center; padding-inline: var(--space-sm);
  background: var(--color-ink); color: var(--color-paper);
  font-family: var(--font-mono); font-size: var(--text-xs);
  letter-spacing: 0.03em; text-transform: uppercase; white-space: nowrap; overflow: hidden;
}
.tband span + span { background: var(--color-accent); color: var(--color-accent-ink); }
.step__n { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--color-muted); font-variant-numeric: tabular-nums; margin-block-start: var(--space-2xs); }
.step__t { font-size: var(--text-md); --opsz: 24; --track: var(--track-xs); --leading: var(--leading-heading); }

/* the rebuild and the refine, each drawn under its own half of the band */
.tpanel-pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-sm); margin-block-start: var(--space-sm); }
.tpanel-pair .tpanel { margin: 0; }

/* the fortnight is a one-page promise: one quiet line under its steps */

/* Custom builds: a second, lighter row. No drawings and no band, so the
   fortnight above stays the lead. */
/* No divider above the second track (2026-09-28, owner: "a lot of lines
   already"): it ran parallel to the step 01 hairline 60px below, with only
   the label between. The space and the label separate the tracks, as the
   first track opens with no line. The space absorbs the old padding. */
.process__custom {
  margin-block-start: calc(var(--space-2xl) + var(--space-lg));
}
/* the two rows are named alike, so they read as a pair: the pricing cards'
   names, in the mono label voice */
/* The track's name: a category label in the sans, not a second serif heading
   (2026-09-28). As a 31px serif title it competed with "How it works." and
   read as flashy; as 10-13px mono caps it was dry. Semibold Switzer at the
   step titles' size, in ink: a different voice from the serif headings, so it
   organises the steps without outranking the section. The pricing cards keep
   serif titles; that is where a plan is chosen. The single-page limit MUST
   stay in the Website transformation caption (the 7 + 7 is single-page only). */
.process__k {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center;
  column-gap: 0.5em; row-gap: var(--space-2xs);
  font-family: var(--font-body); font-weight: 600; font-size: var(--text-md);
  letter-spacing: -0.01em; line-height: 1.2; color: var(--color-ink);
}
/* the wordmark's blue square in front: marks it as a category, not a heading
   (headings never carry it), without a box or another line */
.process__k::before {
  content: ""; grid-row: 1;
  inline-size: 0.5em; block-size: 0.5em;
  background: var(--color-accent);
}
/* the detail line sits under the name, aligned with the word, not the square */
.process__meta {
  grid-column: 2;
  font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 400;
  letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted);
}
.process__k--first { margin-block-start: var(--space-xl); }
.process__k--first + .track { margin-block-start: var(--space-md); }
.ctrack {
  display: grid; grid-template-columns: 1.25fr 1fr 1fr; column-gap: var(--space-lg); row-gap: var(--space-2xs);
  margin: var(--space-md) 0 0; padding: 0; list-style: none;
}
/* rows are a subgrid so the three titles and the three details line up */
.cstep {
  display: grid; grid-row: span 3; grid-template-rows: subgrid; row-gap: var(--space-2xs);
  /* A solid ink rule, the same mark as the fortnight's moments. It was a
     dashed border ("scoped" in the pricing card's language); the owner found
     the full-width dashed line generic, and drawn longer dashes still read as
     a divider. The two rows are labelled, so dashes weren't needed to tell
     them apart. One kind of line in the section. */
  padding-block-start: var(--space-sm); border-block-start: 1px solid var(--color-rule);   /* matches the step hairlines above */
  min-inline-size: 0;
}
/* 01: what we build, the form's own choices. "Something else" is dashed,
   like everything scoped with you. */
/* two classes: the general .chips rule further down sets margin at equal
   specificity and, coming later, silently won (chips sat 4px above the sheets).
   The extra 0.55rem is the sheet rows' own top padding: aligned by box edge,
   the chip text sat 9px above "What gets built"; the eye reads text lines
   across columns, so the first chip line now sits on the first row's line. */
.cstep .cstep__chips { margin-block-start: calc(var(--space-md) + 0.55rem); gap: 0.9rem var(--space-2xs);   /* row gap: chip lines on the sheet rows' 44px rhythm */ align-self: start; align-items: flex-start; align-content: flex-start; }
.cstep__chips .chip { font-size: var(--text-sm); border-color: var(--color-rule); color: var(--color-ink-2); }
.cstep__chips .chip--else { border-style: dashed; border-color: var(--color-muted); color: var(--color-muted); }
/* 02 and 03: small ruled sheets, in the voice of the fortnight's sign-off */
/* hairline top: the step above already carries the bold rule, and two bold
   rules a title apart read as a double line */
.cstep__sheet { margin: var(--space-md) 0 0; align-self: start; border-block-start: var(--rule-hair) solid var(--color-rule); }   /* light like the rows (was ink) */
.cstep__sheet div {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-sm);
  padding-block: 0.55rem; border-block-end: var(--rule-hair) solid var(--color-rule);
}
.cstep__sheet dt {
  font-family: var(--font-mono); font-size: var(--text-sm); letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--color-ink-2); min-inline-size: 0;   /* a step up from text-xs muted: too dry (owner, 2026-09-28) */
}
.cstep__sheet dd {
  margin: 0; flex: none;
  font-family: var(--font-display); font-variation-settings: "opsz" 24, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: var(--text-base); color: var(--color-ink);
}
.cstep__t {
  font-family: var(--font-display); font-variation-settings: "opsz" 24, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: var(--text-base); line-height: var(--leading-heading); color: var(--color-ink);
}

/* ── the panels ──────────────────────────────────────────────────────────────
   Everything inside is sized in cqmin off the panel, which is a SIZE container
   (its height is always definite), so one drawing serves a 150px half and a
   full-width phone column. The panel's own padding is percent, not cq units:
   a container cannot measure itself. Each drawing plays once, the first time
   its panel is in view (JS arms the track and marks panels .is-in); without
   JS, or with reduced motion, every drawing simply shows its finished state. */
.tpanel {
  container-type: size;
  block-size: clamp(9.5rem, 13vw, 12rem);
  margin-block-start: var(--space-sm);
  border: var(--rule-hair) solid var(--color-rule);
  background: var(--color-paper);
  overflow: hidden;
  border-radius: var(--radius-lg);
}

.tpanel__art {
  block-size: 100%;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  padding: 6cqmin;
}
.tpanel__art b, .tpanel__art i, .tpanel__art u, .tpanel__art em, .tpanel__art s {
  display: block; font-style: normal; font-weight: inherit; text-decoration: none;
}

/* 01 — the address field, being typed */
.pa-url { align-items: stretch; max-inline-size: 130cqmin; margin-inline: auto; gap: 3cqmin; }
.pa-url__k { font-family: var(--font-mono); font-size: 5cqmin; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.pa-url__v {
  display: flex; align-items: center;
  padding-block: 2cqmin; border-block-end: var(--rule-bold) solid var(--color-ink);
  font-size: 13cqmin; line-height: 1.1; color: var(--color-ink);
}
.pa-url__type { white-space: nowrap; overflow: hidden; }
.pa-url__caret { inline-size: 0.6cqmin; min-inline-size: 1px; block-size: 12cqmin; margin-inline-start: 0.8cqmin; background: var(--color-accent); }
.pa-url__btn {
  align-self: flex-start; margin-block-start: 3cqmin;
  padding: 2.4cqmin 5cqmin; background: var(--color-ink); color: var(--color-paper);
  font-size: 5.6cqmin;
}
.track.armed .tpanel .pa-url__type { animation: type-in 1.1s steps(15, end) 0.2s both; }
.track.armed .tpanel .pa-url__caret { animation: caret 0.9s steps(1) infinite; }
@keyframes type-in { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes caret { 50% { opacity: 0; } }

/* 02 — the audit: what the client gets back. A ruled sheet in the same
   voice as the sign-off (04). The accent appears once, under the quote. */
.pa-audit { align-items: stretch; max-inline-size: 150cqmin; margin-inline: auto; gap: 0; }
.pa-audit__k {
  font-family: var(--font-mono); font-size: 4.6cqmin; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--color-muted); padding-block-end: 3cqmin; border-block-end: var(--rule-bold) solid var(--color-ink);
}
.pa-audit__row {
  display: flex; align-items: baseline; gap: 3.5cqmin;
  padding-block: 3.4cqmin; border-block-end: var(--rule-hair) solid var(--color-rule);
}
.pa-audit__n { font-family: var(--font-mono); font-size: 4.4cqmin; color: var(--color-muted); }
.pa-audit__t {
  flex: 1; min-inline-size: 0; white-space: nowrap;
  font-family: var(--font-display); font-variation-settings: "opsz" 24, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: 7.4cqmin; line-height: 1.1; color: var(--color-ink);
}
.pa-audit__ok {
  flex: none; align-self: center; inline-size: 2.6cqmin; block-size: 5cqmin; margin-inline-end: 1.4cqmin;
  border: solid var(--color-ink); border-width: 0 max(1.5px, 0.7cqmin) max(1.5px, 0.7cqmin) 0;
  transform: translateY(-15%) rotate(45deg);
}
.pa-audit .pa-audit__sar {
  display: flex; align-items: center; gap: 1.6cqmin; font-family: var(--font-mono); font-size: 4.6cqmin;
  letter-spacing: 0.03em; color: var(--color-muted);
}
.pa-audit__sar i {
  inline-size: 16cqmin; block-size: 5cqmin; background: var(--color-paper-3);
  box-shadow: 0 max(2px, 0.9cqmin) 0 -0.1cqmin var(--color-accent);
  transform-origin: left;
}
.pa-audit__foot {
  padding-block-start: 3.4cqmin; font-family: var(--font-mono); font-size: 4.2cqmin;
  letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-ink-2);
}
.track.armed .tpanel .pa-audit__row, .track.armed .tpanel .pa-audit__foot { animation: note-in 0.35s var(--ease-out) both; }
.track.armed .tpanel .pa-audit__row:nth-child(2) { animation-delay: 0.2s; }
.track.armed .tpanel .pa-audit__row:nth-child(3) { animation-delay: 0.55s; }
.track.armed .tpanel .pa-audit__row:nth-child(4) { animation-delay: 0.9s; }
.track.armed .tpanel .pa-audit__sar i { animation: pa-fill 0.5s var(--ease-out) 1.25s both; }
.track.armed .tpanel .pa-audit__foot { animation-delay: 1.8s; }
@keyframes pa-fill { from { transform: scaleX(0); } to { transform: none; } }
@keyframes note-in { from { opacity: 0; transform: translateX(-2cqmin); } to { opacity: 1; transform: none; } }

/* 03 — seven days, the page a little more complete each day */
.pa-days { flex-direction: row; align-items: stretch; gap: 2.5cqmin; }
.pa-day { flex: 1 1 0; max-inline-size: 26cqmin; display: flex; flex-direction: column; gap: 2cqmin; min-inline-size: 0; }
.pa-day__n { font-family: var(--font-mono); font-size: 3.6cqmin; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); white-space: nowrap; }
.pa-day__pg {
  flex: 1; display: flex; flex-direction: column; gap: 2.4cqmin;
  padding: 3cqmin; border: var(--rule-hair) solid var(--color-rule);
}
.pa-day__pg b  { block-size: 7cqmin; inline-size: 80%; background: var(--color-ink); }
.pa-day__pg i  { block-size: 1.2cqmin; background: var(--color-rule); }
.pa-day__pg i + i { inline-size: 65%; }
.pa-day__pg u  { flex: 1; min-block-size: 8cqmin; background: var(--color-paper-3); }
.pa-day__pg em { block-size: 4.5cqmin; inline-size: 55%; background: var(--color-accent); }
/* what exists on each day — cumulative */
.pa-day--1 .pa-day__pg > *               { visibility: hidden; }
.pa-day--2 .pa-day__pg > :not(b)         { visibility: hidden; }
.pa-day--3 .pa-day__pg > :is(u, em)      { visibility: hidden; }
.pa-day--3 .pa-day__pg i + i             { visibility: hidden; }
.pa-day--4 .pa-day__pg > :is(u, em)      { visibility: hidden; }
.pa-day--5 .pa-day__pg > em              { visibility: hidden; }
.pa-day--6 .pa-day__pg > em              { background: var(--color-neutral); }
.track.armed .tpanel .pa-day { animation: day-in 0.35s var(--ease-out) both; }
.track.armed .tpanel .pa-day--2 { animation-delay: 0.15s; }
.track.armed .tpanel .pa-day--3 { animation-delay: 0.3s; }
.track.armed .tpanel .pa-day--4 { animation-delay: 0.45s; }
.track.armed .tpanel .pa-day--5 { animation-delay: 0.6s; }
.track.armed .tpanel .pa-day--6 { animation-delay: 0.75s; }
.track.armed .tpanel .pa-day--7 { animation-delay: 0.9s; }
@keyframes day-in { from { opacity: 0; transform: translateY(3cqmin); } to { opacity: 1; transform: none; } }

/* 04 — your notes on the finished page, each resolved */
.pa-refine { flex-direction: row; gap: 8cqmin; }
.pa-mini {
  inline-size: 62cqmin; block-size: 78cqmin; flex: none;
  display: flex; flex-direction: column; gap: 3cqmin;
  padding: 5cqmin; border: var(--rule-hair) solid var(--color-rule);
}
.pa-mini b  { block-size: 9cqmin; inline-size: 82%; background: var(--color-ink); }
.pa-mini i  { block-size: 1.4cqmin; background: var(--color-rule); }
.pa-mini i + i { inline-size: 60%; }
.pa-mini u  { flex: 1; background: var(--color-paper-3); }
.pa-mini em { block-size: 6cqmin; inline-size: 50%; background: var(--color-accent); }
.pa-notes { display: flex; flex-direction: column; gap: 5cqmin; }
.pa-note { display: flex; align-items: center; gap: 3cqmin; font-size: 6.6cqmin; color: var(--color-ink-2); white-space: nowrap; }
/* resolved is the resting state: the pin is done, so it is ink, not accent */
.pa-pin {
  display: grid; place-items: center; flex: none;
  inline-size: 8.5cqmin; block-size: 8.5cqmin; border-radius: 50%;
  background: var(--color-ink); color: var(--color-paper);
  font-family: var(--font-mono); font-size: 4.4cqmin;
}
/* refine week as quality checks (owner, 2026-09-26): a drawn tick in the pin,
   not a number, so it reads as "done", not as a list of client nitpicks */
.pa-pin--ok::before {
  content: ""; inline-size: 28%; block-size: 50%;
  border: solid var(--color-paper); border-width: 0 max(1.5px, 0.6cqmin) max(1.5px, 0.6cqmin) 0;
  transform: translateY(-12%) rotate(45deg);
}
.track.armed .tpanel .pa-pin { animation: pin-raise 0.3s var(--ease-out) both, pin-resolve 0.3s var(--ease-out) both; }
.track.armed .tpanel .pa-note:nth-child(1) .pa-pin { animation-delay: 0.1s, 1.2s; }
.track.armed .tpanel .pa-note:nth-child(2) .pa-pin { animation-delay: 0.35s, 1.5s; }
.track.armed .tpanel .pa-note:nth-child(3) .pa-pin { animation-delay: 0.6s, 1.8s; }
@keyframes pin-raise   { from { transform: scale(0); background: var(--color-accent); } to { transform: scale(1); background: var(--color-accent); } }
@keyframes pin-resolve { from { background: var(--color-accent); } to { background: var(--color-ink); } }

/* 05 — sign-off first, then the invoice */
.pa-sign { align-items: stretch; max-inline-size: 140cqmin; margin-inline: auto; gap: 0; }
.pa-sign__row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 6cqmin;
  padding-block: 5cqmin; border-block-end: var(--rule-hair) solid var(--color-rule);
}
.pa-sign__row--1 { border-block-start: var(--rule-bold) solid var(--color-ink); }
.pa-sign__k { font-family: var(--font-mono); font-size: 5cqmin; letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.pa-sign__row b {
  font-family: var(--font-display); font-variation-settings: "opsz" 48, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: 13cqmin; line-height: 1; letter-spacing: var(--track-md); color: var(--color-ink);
}
.track.armed .tpanel .pa-sign__row { animation: note-in 0.4s var(--ease-out) both; }
.track.armed .tpanel .pa-sign__row--2 { animation-delay: 0.9s; }

/* Narrow panels (anything closer to square than 3:2 — the desktop columns
   and the halves under the band): the refine sketch shrinks so its notes fit beside it. */
@container (aspect-ratio < 1.5) {
  .pa-refine { gap: 5cqmin; }
  .pa-mini { inline-size: 38cqmin; block-size: 60cqmin; }
  .pa-note { font-size: 5.2cqmin; white-space: normal; }
  .pa-url__v { font-size: 10cqmin; }
  .pa-sign__row b { font-size: 10cqmin; }
}

/* Armed drawings wait at their first frame until their panel is in view.
   !important because each drawing's own animation shorthand (more specific)
   would reset the play state to running. */
.track.armed .tpanel:not(.is-in) * { animation-play-state: paused !important; }

/* Taller than wide (the halves under the band on a phone): the page sits
   above its notes, so each note keeps one line. */
@container (aspect-ratio < 1) {
  .pa-refine { flex-direction: column; align-items: center; gap: 5cqmin; }
  .pa-mini { inline-size: 56cqmin; block-size: 44cqmin; padding: 4cqmin; gap: 2.4cqmin; }
  .pa-notes { gap: 3.5cqmin; }
  .pa-note { font-size: 7cqmin; white-space: nowrap; gap: 2.5cqmin; }
  .pa-pin { inline-size: 7.5cqmin; block-size: 7.5cqmin; font-size: 4.4cqmin; }
}

@media (prefers-reduced-motion: reduce) {
  .track .tpanel * { animation: none !important; }
}

/* ============================================================ in their words
   The clients' marks and one line, then three short quotes in the display
   face with a name and company under each. No stars, no portraits. */
/* A deeper paper, edge to edge (2026-09-27): after the carousel, five paper
   sections ran together (How it works, quotes, Pricing, Who's behind, FAQ).
   The quotes become a pause between the process and the price. Same cream
   family, one step down: NOT a third dark band. The shell is capped at
   84rem, so the tone bleeds to the viewport edges with a spread shadow,
   clipped to the section's own height. The hairlines above and below give
   way to the tone change.
   2026-09-28: the band is gone. On the neutral greys a step-darker band read
   as shaded, even disabled. White quote cards were tried next and dropped
   the same day: the stock testimonial grid, and a second row of white cards
   straight after the pricing ones. Then vertical dividers with larger type,
   also dropped: the middle quote ran to 6 lines against 4 and the lines
   framed the gaps. Back to the original row (a rule over each quote, the
   original size, 3 · 4 · 3 lines), with the rule a light hairline. */
.band.words, .words + .band { border-block-start: 0; }

/* Squarespace's avatars-and-claim, with the clients' own marks: overlapping
   circles, each ringed in paper so the overlap reads as a stack, then one
   centred line at display size. */
.words__head { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--space-lg); }
.words__lede { display: flex; flex-direction: column; align-items: center; gap: var(--space-md); }
.words__sub { margin: 0; font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.words__title {
  max-inline-size: 24ch; text-wrap: balance;   /* "What our clients are saying." on one line where it fits (was 16ch, set for a longer heading) */
  font-size: var(--text-2xl); --opsz: 72; --track: var(--track-lg); line-height: 1.05;
}
.words__row {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-lg);
  margin-block-start: var(--space-2xl);
}
/* Post-style cards (2026-09-29, owner, after mobbin.com's testimonials):
   a white card with a hairline edge, the person first (avatar + company
   badge, name, company), then their words in plain body text, no quote
   marks. It reads like someone talking, not a pull-quote. (White cards
   around the big serif quotes were tried on 2026-09-27 and felt "meh"; the
   difference here is the post shape and the body type.) White is the
   site's "raised" colour, as the pricing cards. */
.word {
  margin: 0; display: flex; flex-direction: column; gap: var(--space-md);
  padding: var(--space-lg);
  background: var(--color-card);
  border: var(--rule-hair) solid var(--color-rule-2);
  border-radius: 24px;
}
.word__q { margin: 0; }
.word__q p {
  font-size: 1.0625rem; line-height: 1.55;
  color: var(--color-ink);
}
.word__who { order: -1; display: flex; align-items: center; gap: var(--space-sm); font-size: var(--text-sm); color: var(--color-ink-2); }
/* The person, then the company (2026-09-29, after mobbin.com's avatar +
   company badge). Clients won't publish their faces, so the person is a
   serif initial (the letter style of "Who's behind Layoutics") in a round
   avatar like Mobbin's, and their company's logo sits on its edge as a small
   round badge,
   ringed in the page colour. Never a stock silhouette: it reads as a fake
   review, and would guess a gender. Until a name is confirmed the tile
   shows "?" with the vermilion dashed placeholder mark (.is-todo): replace
   it with the person's initial and drop the class. */
.word__av { position: relative; flex: none; }
.word__mono {
  display: grid; place-items: center;
  inline-size: 3rem; block-size: 3rem; border-radius: 50%;   /* round, as Mobbin's profile pictures (owner) */
  background: var(--color-paper-2); border: var(--rule-hair) solid var(--color-rule);
  font-family: var(--font-display); font-variation-settings: "opsz" 72, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: 1.4rem; line-height: 1; color: var(--color-ink);
}
.word__mono.is-todo { color: var(--color-muted); border: 1px dashed var(--color-error); }
.word__badge {
  position: absolute; inset-block-end: -3px; inset-inline-end: -5px;
  display: grid; place-items: center; overflow: hidden;
  inline-size: 1.4rem; block-size: 1.4rem; border-radius: 50%;
  background: var(--color-paper-2);
  box-shadow: 0 0 0 2px var(--color-card), 0 2px 6px oklch(20% 0.005 270 / 0.14);   /* ringed in the card's white */
}
.word__badge img { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }
/* EuroDecor's mark is square on white (2026-09-30): inset so the circle
   doesn't cut its corners (a square fits a circle at ~70% of its width) */
.word__badge img[src*="eurodecor"] { box-sizing: border-box; padding: 3px; object-fit: contain; background: #fff; }
/* Spa Station's pebble (owner, 2026-10-10), cropped to the pebble on white:
   inset a little less, as it is already rounded */
.word__badge img[src*="spastation"] { box-sizing: border-box; padding: 2px; object-fit: contain; background: #fff; }
.word__badge b {   /* a client's initial, for a client whose logo hasn't come yet (none now) */
  font-family: var(--font-display); font-variation-settings: "opsz" 36, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: 0.7rem; line-height: 1; color: var(--color-ink);
}
.word__id { display: flex; flex-direction: column; gap: 2px; min-inline-size: 0; }
.word__id .foot__todo { align-self: flex-start; }
.word__name { color: var(--color-ink); font-weight: 600; font-size: var(--text-base); line-height: 1.3; }
/* in the post card the company is plain grey text, as Mobbin's, not the
   section labels' mono caps: it should read like a byline */
.word .word__co { font-family: var(--font-body); font-size: 0.9375rem; letter-spacing: 0; text-transform: none; color: var(--color-muted); line-height: 1.3; }
.word__co { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.word__co .foot__todo { font-size: inherit; }   /* a placeholder company keeps the company line's size */
@media (max-width: 48rem) {
  .words__row { grid-template-columns: minmax(0, 1fr); gap: var(--space-md); margin-block-start: var(--space-xl); }
  .words__title { font-size: var(--text-xl); --opsz: 48; --track: var(--track-md); }
  }

/* ============================================================ pricing (#offer)
   Reworked the Squarespace way (2026-09-26). The anatomy is the point: both
   cards carry the same parts in the same order (name, who it's for, price at
   the largest size, note, one button, then The work / Timeline / After
   launch), so the eye compares straight across. Paper with an ink top rule, NOT a third dark surface.
   No pay-only-if-happy line anywhere (owner, 2026-09-21), no badge (owner,
   2026-09-26), no 7 + 7 band (How it works draws it). */
.offer {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--space-xl);
}
.offer__head { text-align: center; }
.offer__title { text-align: center; }
/* the risk-lowering line under the heading, Squarespace's "Free for 14 days" */
.offer__sub { margin-block-start: var(--space-sm); color: var(--color-ink-2); font-size: var(--text-md); line-height: 1.4; text-wrap: balance; }

.card {
  display: flex; flex-direction: column;
  padding: var(--space-xl);
  /* white, raised on the grey, with a hairline (2026-09-28). The heavy ink
     top rule went with the rounded corners: on a curve it bent around the
     corners and thinned out at the sides, which read as a glitch. */
  border: var(--rule-hair) solid var(--color-rule-2);
  background: var(--color-card);
  border-radius: var(--radius-lg);
}
/* Two plans side by side. Rows are a subgrid, so each part of one card
   lines up with the same part of the other (a two-line note or sub never
   pushes one button below its neighbour). */
.offer__cards {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--space-lg);
  inline-size: min(100%, 66rem);
}
.offer__cards .card { display: grid; grid-row: span 8; grid-template-rows: subgrid; row-gap: 0; }
/* The plan's name is the card's title (2026-09-28, owner: "needs better
   attention"): the display serif, sentence case, below the price in size so
   the price still leads. It was 12.8px mono caps, the smallest type in the card. */
.card__name {
  font-family: var(--font-display); font-variation-settings: "opsz" 48, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: var(--text-xl); letter-spacing: var(--track-md); line-height: 1.1;
  color: var(--color-ink);
}
.card__sub { margin-block-start: var(--space-xs); color: var(--color-ink-2); font-size: var(--text-base); text-wrap: balance; }
.card__price {
  margin-block-start: var(--space-xl);
  font-family: var(--font-display); font-variation-settings: "opsz" 72, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: var(--text-3xl); letter-spacing: var(--track-xl); line-height: 1;
  color: var(--color-ink);
}
/* "From SAR" rides small beside the figure, the way "/mo" does */
.card__from {
  font-family: var(--font-body); font-variation-settings: normal;
  font-weight: 500; font-size: var(--text-md); letter-spacing: 0; vertical-align: 0.15em;
  color: var(--color-ink-2);
}
.card__note { margin-block-start: var(--space-sm); color: var(--color-ink-2); font-size: var(--text-sm); text-wrap: pretty; }
/* the safety net for SMEs under the floor (owner, 2026-09-27): its own line so it is seen, not a clause at the end */
.card__budget { display: block; margin-block-start: var(--space-2xs); color: var(--color-ink); text-wrap: pretty; }
.card__cta { justify-content: center; margin-block-start: var(--space-lg); align-self: start; }
.card__group { margin-block-start: var(--space-lg); padding-block-start: var(--space-md); border-block-start: var(--rule-hair) solid var(--color-rule); }
.card__gk {
  font-family: var(--font-mono); font-size: var(--text-xs);
  letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted);
}
.card__list {
  list-style: none; margin: var(--space-sm) 0 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--space-xs);
}
.card__list li { display: flex; align-items: baseline; gap: var(--space-sm); color: var(--color-ink); text-wrap: pretty; }
/* a drawn tick, in ink: the accent is the correction mark, not a bullet */
.card__list li::before {
  content: ""; flex: none;
  inline-size: 0.35em; block-size: 0.65em;
  border: solid var(--color-ink); border-width: 0 2px 2px 0;
  transform: translateY(-0.1em) rotate(45deg);
}


.chips {
  list-style: none; margin: var(--space-sm) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--space-xs);
}
.chip {
  padding: 0.5em 0.95em;
  border: var(--rule-hair) solid var(--color-ink);
  font-size: var(--text-base);
  line-height: 1.2;
  color: var(--color-ink);
  white-space: nowrap;
  border-radius: var(--radius-sm);
}

/* ============================================================ who's behind Layoutics
   The FAQ's own grid (title left, content right), so the two read as one
   closing run before the form. One compact row of people, not a team grid. */
.about {
  display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: var(--space-xl); align-items: start;
}
.about__title { font-size: var(--text-2xl); --opsz: 72; --track: var(--track-lg); max-width: 11ch; }
.about__p { margin-block-start: var(--space-md); max-inline-size: 30rem; color: var(--color-ink-2); text-wrap: pretty; }
.about__people {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-xl) var(--space-lg);
  margin: 0; padding: 0; list-style: none;   /* no rule above it on desktop (owner, 2026-10-01): half-width, it lined up with nothing on the left; phones keep theirs */
}
.person { display: flex; gap: var(--space-md); align-items: flex-start; min-inline-size: 0; }
/* No photos, by the owner's choice (2026-09-27): each person gets a one-letter
   serif monogram (.person__photo--ini). One letter, because the founder's two
   ("AI") read as artificial intelligence here. An <img> would still fit the box. */
.person__photo {
  flex: none; display: grid; place-items: center;
  inline-size: 4rem; block-size: 4rem; border-radius: var(--radius-md); overflow: hidden;
  background: var(--color-paper-2); border: var(--rule-hair) solid var(--color-rule);
  font-family: var(--font-mono); font-size: var(--text-sm); letter-spacing: 0.03em; color: var(--color-muted);
}
.person__photo img { inline-size: 100%; block-size: 100%; object-fit: cover; }
.person__photo--ini {
  font-family: var(--font-display); font-variation-settings: "opsz" 72, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: 2rem; line-height: 1; letter-spacing: 0; color: var(--color-ink);
}
/* the partner network is openly not a person: an icon on ink, not a face */
.person--network .person__photo { background: var(--color-ink); border-color: var(--color-ink); color: var(--color-paper); }
.person--network .person__photo svg { inline-size: 1.75rem; block-size: 1.75rem; fill: currentColor; }
.person__body { min-inline-size: 0; }
.person__name { font-family: var(--font-display); font-variation-settings: "opsz" 24, "SOFT" 0, "WONK" 0; font-weight: 600; font-size: var(--text-md); line-height: 1.2; color: var(--color-ink); }
.person__role { margin-block-start: 2px; font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.person__line { margin-block-start: var(--space-xs); font-size: var(--text-sm); color: var(--color-ink-2); }
.person__link { display: inline-flex; align-items: center; min-block-size: 36px; font-size: var(--text-sm); color: var(--color-ink); text-underline-offset: 4px; }
.person__link:hover { text-decoration-color: var(--color-accent); }
/* The open seat (owner, 2026-09-30): a dashed empty tile with a "+", not a
   face. Not functional until Layoutics hires: hover, focus or a tap only
   raises a small label saying so. When hiring starts, point it at the form. */
.person__open {
  position: relative; display: flex; gap: var(--space-md); align-items: inherit; min-inline-size: 0;
  margin: 0; padding: 0; border: 0; background: none; font: inherit; color: inherit;
  text-align: start; cursor: help;
}
.person__open .person__name, .person__open .person__role { display: block; }
.person--open .person__photo {
  background: none; border: 1px dashed var(--t-dash); color: var(--color-muted);
  transition: border-color 160ms var(--ease-out), color 160ms var(--ease-out);
}
.person--open .person__photo svg { inline-size: 1.5rem; block-size: 1.5rem; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
.person--open .person__name { color: var(--color-ink-2); }
.person__tip {
  position: absolute; inset-block-end: calc(100% + 8px); inset-inline-start: 0; z-index: 5;
  padding: 3px 8px; border-radius: 6px; white-space: nowrap; pointer-events: none;
  font: 500 12px/16px var(--font-body); letter-spacing: 0;
  background: var(--t-ink); color: var(--color-paper);
  box-shadow: 0 4px 12px rgb(0 0 0 / 0.16);
  opacity: 0; translate: 0 4px;
  transition: opacity 160ms var(--ease-out), translate 200ms var(--ease-out);
}
@media (hover: hover) {
  .person__open:hover .person__photo { border-color: var(--color-muted); color: var(--color-ink); }
  .person__open:hover .person__tip { opacity: 1; translate: 0 0; transition-delay: 150ms; }
}
.person__open:focus-visible .person__tip, .person--open.is-tip .person__tip { opacity: 1; translate: 0 0; }
/* stacks where the FAQ stacks, so the two stay one run */
@media (max-width: 48rem) {
  .about { grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); }
  .about__title { font-size: var(--text-xl); --opsz: 48; --track: var(--track-md); }
}
@media (max-width: 40rem) { .about__people { grid-template-columns: minmax(0, 1fr); } }

/* ============================================================ C1b · questions
   Two columns: the heading holds the left, the questions run down the right
   between hairlines. Each row is a native <details>, so it opens without JS,
   works with find-in-page, and `name` makes it one-at-a-time where supported.
   The height transition is progressive: browsers without ::details-content
   drop the whole rule and simply snap open. */
.faq {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: var(--space-xl);
  align-items: start;
}
.faq__title {
  font-size: var(--text-2xl); --opsz: 72; --track: var(--track-lg);
  max-width: 11ch;
}
.faq__list { border-block-start: var(--rule-hair) solid var(--color-ink-2); }
.faq__item {
  border-block-end: var(--rule-hair) solid var(--color-ink-2);
  interpolate-size: allow-keywords;
}
.faq__q {
  list-style: none;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-md);
  padding-block: var(--space-lg);
  padding-inline: var(--space-sm);
  font-size: var(--text-md);
  line-height: 1.35;
  color: var(--color-ink);
  cursor: pointer;
  text-wrap: pretty;
}
.faq__q::-webkit-details-marker { display: none; }
/* The plus, drawn from two hairlines; open, it turns 45° into the close mark. */
.faq__q::after {
  content: "";
  flex: none;
  inline-size: 1.15em; block-size: 1.15em;
  background:
    linear-gradient(currentColor, currentColor) center / 100% 1.5px no-repeat,
    linear-gradient(currentColor, currentColor) center / 1.5px 100% no-repeat;
  transition: transform 0.35s var(--ease-out);
}
.faq__item[open] > .faq__q::after { transform: rotate(45deg); }
.faq__q:focus-visible { outline: var(--rule-bold) solid var(--color-accent); outline-offset: -2px; }
.faq__a {
  padding-inline: var(--space-sm);
  padding-block-end: var(--space-xl);
}
.faq__a p {
  max-width: 60ch;
  font-size: var(--text-md);
  line-height: 1.65;
  color: var(--color-ink);
  text-wrap: pretty;
}
.faq__item::details-content {
  block-size: 0;
  overflow: clip;
  transition: block-size 0.4s var(--ease-out), content-visibility 0.4s allow-discrete;
}
.faq__item[open]::details-content { block-size: auto; }

@media (prefers-reduced-motion: reduce) {
  .faq__q::after, .faq__item::details-content { transition: none; }
}
@media (max-width: 48rem) {
  .faq { grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); }
  .faq__title { font-size: var(--text-xl); --opsz: 48; --track: var(--track-md); }
  .faq__q, .faq__a p { font-size: var(--text-base); }
  .faq__q { padding-block: var(--space-md); padding-inline: 0; }
  .faq__a { padding-inline: 0; padding-block-end: var(--space-lg); }
}

/* ============================================================ C2 · the ask */

/* Light since 2026-09-28 (owner): the page's grey with the hero's blue glow,
   stronger and set behind the heading, so the first and last screens are
   bookends (grey, a blue glow, an ink button) and everything between is the
   proof. It was an ink band shared with the footer; the footer stays dark. */
.ask {
  color: var(--color-ink);
  background:
    radial-gradient(ellipse 48% 52% at 24% 48%, var(--color-glow-form), transparent 72%),
    var(--color-paper);
}
/* no rule and no edge between the FAQ and the form: the glow, sized to fade
   out inside the band on every side, is the only thing that says "here" */
.ask.band { border-block-start: 0; }
/* stacked, the heading is at the top of the band, so the glow goes with it */
@media (max-width: 60rem) {
  .ask { background: radial-gradient(ellipse 90% 19% at 30% 21%, var(--color-glow-form), transparent 72%), var(--color-paper); }
}
.ask h2 { font-size: var(--text-3xl); --track: var(--track-xl); --leading: var(--leading-tight); max-width: 12ch; }
/* Tops aligned, not bottoms. end-alignment balanced a two-field form; the
   third field made the form taller than the intro and stranded the heading
   at the bottom under 182 px of void. Space below a block reads as breathing
   room, space above it reads as a mistake. */
.ask__grid { display: grid; grid-template-columns: 5fr 7fr; gap: var(--space-xl) var(--space-3xl); align-items: start; }
.ask__p { color: var(--color-ink-2); max-width: 46ch; margin-block-start: var(--space-md); }
.field { display: flex; flex-direction: column; gap: var(--space-2xs); }
.field label { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.field input {
  font-family: var(--font-body);
  font-size: var(--text-md);
  color: var(--color-ink);
  /* white boxes on the grey (were underlines on the ink band) */
  background: var(--color-card);
  border: var(--rule-hair) solid var(--color-rule);
  padding: var(--space-sm) var(--space-md);
  min-height: 52px;
  border-radius: var(--radius-md);
  transition: border-color var(--dur-short) var(--ease-out), box-shadow var(--dur-short) var(--ease-out);
}
.field input::placeholder { color: var(--color-neutral); opacity: 1; }
/* Phones keep the promise ("quote before any work, no obligation") and drop
   the call/meet sentence (owner, 2026-09-28): the Phone or WhatsApp field
   already says it, and the form starts a screen sooner. */
@media (max-width: 40rem) { .ask__more { display: none; } }
/* Phones (owner, 2026-09-28): 20px entries in 52px boxes read far bigger than
   the service chips above them. 16px is the floor: below it iOS zooms the
   page on focus. Boxes to 46px, the same scale as the 40px chips. */
@media (max-width: 40rem) {
  .field input { font-size: 1rem; min-height: 46px; padding: 0.6rem 0.9rem; }
}

/* The .field input rules are written for the text inputs. The opt-out checkbox
   is not one, and was inheriting their 48 px min-height and underline, which
   pushed the box onto its own line above the words. Geometry only — the mono
   uppercase treatment is deliberate and matches the field labels. */
.field__opt {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  min-height: 44px;
  cursor: pointer;
}
.field__opt input[type="checkbox"] {
  flex: none;
  inline-size: 0.9rem;
  block-size: 0.9rem;
  min-height: 0;
  padding: 0;
  margin: 0;
  border: 0; background: none;
  accent-color: var(--color-accent);
  cursor: pointer;
}
.field input:hover { border-color: var(--color-neutral); }
.field input:focus { outline: none; border-color: var(--color-accent); box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-accent) 18%, transparent); }
.field input:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  border-color: var(--color-rule);
}
.form { display: grid; gap: var(--space-lg); }
/* What do you need? — checkbox chips, several picks allowed (radios until
   2026-09-28). The input stays in the accessibility tree (visually hidden),
   so Tab, Space and focus work natively. */
.need { border: 0; margin: 0; padding: 0; min-inline-size: 0; }
.need legend {
  padding: 0; margin-block-end: var(--space-xs);
  font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.03em;
  text-transform: uppercase; color: var(--color-muted);
}
.need__opts { display: flex; flex-wrap: wrap; gap: var(--space-xs); }
.need__opt { position: relative; cursor: pointer; flex: 1 1 auto; }   /* every row fills the width, both edges even at any width (owner, 2026-09-28) */
.need__opt input { position: absolute; opacity: 0; inline-size: 1px; block-size: 1px; }
.need__opt span {
  display: flex; align-items: center; justify-content: center; min-block-size: 40px;
  padding: 0 var(--space-sm);
  background: var(--color-card);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-sm);
  font-family: var(--font-body); font-size: var(--text-sm); letter-spacing: 0; text-transform: none;   /* the .field label style would otherwise make these mono caps */
  color: var(--color-ink); white-space: nowrap;
  transition: background-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out), border-color var(--dur-short) var(--ease-out);
}
/* Several picks allowed (2026-09-28): the standard multi-select cue, a
   quiet + on each chip ("add this") that turns into a check once picked. */
.need__opt span { gap: 0.5rem; }
.need__opt span::before {
  content: ""; flex: none; inline-size: 10px; block-size: 10px;
  background:
    linear-gradient(currentColor, currentColor) center / 100% 1.5px no-repeat,
    linear-gradient(currentColor, currentColor) center / 1.5px 100% no-repeat;
  opacity: 0.5;
}
.need__opt input:checked + span::before {
  inline-size: 5px; block-size: 10px; margin-inline: 2px 1px; box-sizing: border-box;
  background: none; opacity: 1;
  border: solid currentColor; border-width: 0 1.75px 1.75px 0;
  transform: translateY(-1px) rotate(45deg);
}
.need__hint { margin-inline-start: 0.5em; letter-spacing: 0.08em; color: var(--color-muted); }   /* was --color-neutral, 3.64:1 at 11px (2026-10-10 check); UNDO: swap back */
.need__opt:hover span { border-color: var(--color-ink-2); }
.need__opt input:checked + span { background: var(--color-accent); border-color: var(--color-accent); color: var(--color-accent-ink); }
.need__opt input:focus-visible + span { outline: var(--rule-bold) solid var(--color-focus); outline-offset: 3px; }
.form__row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-lg); }
.form__submit { justify-self: start; }   /* the ink button, like the hero's */
/* the note belongs to the button: directly under it, half the form's gap
   away. It used to sit below the (usually empty) status line and read as a
   stray line at the foot of the form. */
.form__note { font-size: var(--text-sm); color: var(--color-muted); margin-block-start: calc(var(--space-sm) - var(--space-lg)); text-wrap: pretty; }
.form__note a { color: inherit; text-underline-offset: 3px; }
.form__note a:hover { color: var(--color-ink); text-decoration-color: var(--color-accent); }
.form__status { font-size: var(--text-sm); min-height: 1.5em; }
.form__status[data-state="error"] { color: var(--color-error); }

/* ============================================================ footer (Squarespace-style)
   Reworked 2026-09-26 after squarespace.com's footer: the brand and one line
   on the left, three link columns on the right, a thin bar underneath, on
   the same night band as the form (.on-ink remaps every token here). */

/* No "Back to top" in the bar: the fixed WhatsApp button owns the
   bottom-right corner and covered it while scrolling (extra bottom padding
   only cleared it at the very end), and the sticky nav's wordmark already
   goes to the top. The bar keeps only the copyright, on the left. */
.foot { padding-block: var(--space-2xl) var(--space-lg); border-block-start: var(--rule-hair) solid var(--color-rule); }
/* The curtain reveal (2026-09-29, from mobbin.com's close): on wide screens
   the footer is pinned under the page and the page lifts off it with
   rounded bottom corners, so the light form ends as a sheet over the night
   band. Sticky, not fixed: the footer stays in flow and the page needs no
   spacer. Only where the whole footer fits in the viewport (it's ~half a
   laptop screen); on phones it's taller than the screen, so they keep the
   normal footer. The form band rounds its own glow (see below); main is
   deliberately not clipped. */
@media (min-width: 60rem) and (min-height: 40rem) {
  main {
    position: relative; z-index: 1;
    background: var(--color-paper);
    border-end-start-radius: var(--radius-reveal, 44px);
    border-end-end-radius: var(--radius-reveal, 44px);
  }
  /* No overflow clip on main (2026-09-29): clipping the whole page to
     rounded corners put the Redesigned iframes, which scroll every frame,
     inside a rounded clip the browser re-masks each frame, and they
     flickered. Only the last section reaches the corners, and a background
     follows its own border-radius without any clipping, so the form band
     carries the curve itself. */
  main > :last-child {
    border-end-start-radius: var(--radius-reveal, 44px);
    border-end-end-radius: var(--radius-reveal, 44px);
  }
  /* The footer tucks up behind the page by the corner radius, so the curve
     keeps showing the night band after the last scroll too. Without it the
     footer's resting place started exactly at main's edge, the corners showed
     the paper body, and the curve "straightened" at the end (owner,
     2026-09-29; Mobbin keeps it). The padding gives the tuck back. */
  .foot {
    position: sticky; bottom: 0; z-index: 0; border-block-start: 0;
    margin-block-start: calc(-1 * var(--radius-reveal, 44px));
    padding-block-start: calc(var(--space-2xl) + var(--radius-reveal, 44px));
  }
}
.foot__top {
  display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: var(--space-2xl) var(--space-xl);
}
.foot__mark { font-size: var(--text-xl); }
/* Squarespace's "A website makes it real": the one line, at display size */
.foot__tagline {
  margin-block-start: var(--space-md); max-inline-size: 18ch;
  font-family: var(--font-display); font-variation-settings: "opsz" 48, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: var(--text-2xl); letter-spacing: var(--track-md); line-height: 1.1;
  color: var(--color-ink);
}
.foot__social { display: flex; gap: var(--space-xs); margin: var(--space-lg) 0 0; padding: 0; list-style: none; }
.foot__icon {
  display: grid; place-items: center; inline-size: 44px; block-size: 44px;
  color: var(--color-muted);
  transition: color var(--dur-short) var(--ease-out);
}
.foot__icon svg { inline-size: 20px; block-size: 20px; fill: currentColor; }
.foot__icon:hover { color: var(--color-ink); }
.foot__icon:focus-visible { outline: var(--rule-bold) solid var(--color-focus); outline-offset: 2px; }

.foot__cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-xl) var(--space-lg); }
.foot__h { font-size: var(--text-nav); font-weight: 600; color: var(--color-ink); }   /* 14px with the links and the nav (was 12.8, 2026-09-28) */
.foot__list { margin: var(--space-sm) 0 0; padding: 0; list-style: none; }
.foot__list li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--space-xs); }
.foot__link {
  display: inline-flex; align-items: center; min-height: 36px;
  font-size: var(--text-nav); color: var(--color-muted);
  text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 5px;
  transition: color var(--dur-short) var(--ease-out), text-decoration-color var(--dur-short) var(--ease-out);
}
.foot__link:hover { color: var(--color-ink); text-decoration-color: var(--color-accent); }
.foot__k {
  min-block-size: 36px; display: inline-flex; align-items: center;
  font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--color-muted);   /* was neutral: 3.1:1 at 10px on the ink; muted reads 5.8:1 (2026-09-28) */
}
/* Contact: label above value, every row alike (2026-09-28). Inline, the
   office address was too long to sit beside its label and dropped under
   it while Email and WhatsApp stayed side by side. */
.foot__list li:has(> .foot__k) { flex-direction: column; align-items: flex-start; gap: 0; padding-block: 0.35rem; }
.foot__list li:has(> .foot__k) .foot__k { min-block-size: 0; }
/* a confirmed detail: the placeholder's size and colour, without the mark */
.foot__v { font-size: var(--text-nav); color: var(--color-muted); }
/* PLACEHOLDER until the owner gives the detail: a vermilion underline, so a
   draft can never pass for a real address. Replace the span with the value. */
.foot__todo {
  font-size: var(--text-sm); color: var(--color-muted);
  border-block-end: 1px dashed var(--color-error);
}
.foot .foot__todo { font-size: var(--text-nav); }   /* footer rows are 14px; the quotes' placeholders stay 12.8 */

.foot__bar a { color: inherit; text-underline-offset: 4px; }
.foot__bar a:hover { color: var(--color-ink); }
.foot__bar {
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--space-sm);
  margin-block-start: var(--space-2xl); padding-block-start: var(--space-md);
  border-block-start: var(--rule-hair) solid var(--color-rule);
  font-size: var(--text-sm); color: var(--color-muted);
}

@media (max-width: 60rem) {
  .foot__top { grid-template-columns: minmax(0, 1fr); }
}
/* The columns are <details> (2026-09-28). Above 40rem app.js keeps them open
   and the summary is only a heading; on phones they fold, as ClickUp's
   footer does: logo and line, three hairline rows with a chevron, the icons,
   the bar. Without JS they all stay open. */
.foot__h { display: block; list-style: none; cursor: default; }
.foot__h::-webkit-details-marker { display: none; }
@media (max-width: 40rem) {
  .foot__top { gap: 0; }
  .foot__brand { display: contents; }               /* lets the icons move below the rows */
  .foot__tagline { font-size: var(--text-xl); margin-block-end: var(--space-xl); max-inline-size: 16ch; text-wrap: balance; }
  .foot__cols { order: 1; display: block; border-block-start: var(--rule-hair) solid var(--color-rule); }
  .foot__social { order: 2; margin-block-start: var(--space-md); margin-inline-start: -12px; }   /* icon glyph on the text edge */
  .foot__col { border-block-end: var(--rule-hair) solid var(--color-rule); }
  .foot__h {
    display: flex; justify-content: space-between; align-items: center;
    min-block-size: 56px; cursor: pointer;
    font-size: var(--text-base);
  }
  .foot__h::after {
    content: ""; inline-size: 7px; block-size: 7px; margin-inline-end: 4px;
    border-inline-end: 1.5px solid var(--color-muted); border-block-end: 1.5px solid var(--color-muted);
    transform: translateY(-2px) rotate(45deg);
    transition: transform var(--dur-short) var(--ease-out);
  }
  .foot__col[open] > .foot__h::after { transform: translateY(2px) rotate(225deg); }
  .foot__h:focus-visible { outline: var(--rule-bold) solid var(--color-focus); outline-offset: -2px; }
  .foot__list { margin: 0 0 var(--space-sm); }
  .foot__link { min-height: 40px; font-size: var(--text-base); }
  .foot__v, .foot .foot__todo { font-size: var(--text-base); }   /* both values 16px (the scoped .foot .foot__todo beat the plain one) */
  .foot__mark { font-size: var(--text-lg); }   /* under the 31px tagline, not level with it (2026-09-28) */
  .foot__list li:has(> .foot__k) { padding-block: 0.55rem; gap: 0.15rem; }   /* air between one value and the next label */
  .foot__k { min-block-size: 40px; }
  .foot__bar { margin-block-start: var(--space-lg); }
}

/* ============================================================ privacy.html
   One reading column on paper: a plain document, not a landing page. */
.legal__nav {
  display: flex; justify-content: space-between; align-items: center;
  padding-block: var(--space-md); border-block-end: var(--rule-hair) solid var(--color-rule);
}
.legal__back { font-size: var(--text-sm); color: var(--color-muted); text-underline-offset: 5px; }
.legal__back:hover { color: var(--color-ink); }
.legal { max-inline-size: 44rem; padding-block: var(--space-2xl) var(--space-3xl); }
.legal__kicker { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-muted); }
.legal__title {
  margin-block-start: var(--space-sm);
  font-family: var(--font-display); font-variation-settings: "opsz" 72, "SOFT" 0, "WONK" 0;
  font-weight: 600; font-size: var(--text-2xl); letter-spacing: var(--track-lg); line-height: 1.05;
}
.legal__date { margin-block-start: var(--space-sm); font-size: var(--text-sm); color: var(--color-muted); }
.legal__lead { margin-block-start: var(--space-lg); font-size: var(--text-md); color: var(--color-ink); }
.legal__sec { margin-block-start: var(--space-xl); padding-block-start: var(--space-md); border-block-start: var(--rule-hair) solid var(--color-rule); }
.legal__sec h2 { font-size: var(--text-md); --opsz: 24; }
.legal__sec p, .legal__sec ul { margin-block-start: var(--space-sm); color: var(--color-ink-2); }
.legal__sec ul { padding-inline-start: 1.1rem; display: flex; flex-direction: column; gap: var(--space-xs); }
.legal__sec b { font-weight: 600; color: var(--color-ink); }
/* 404.html: the same frame, a short page, held off the top of a tall window */
.legal--404 { min-block-size: 70vh; padding-block-start: clamp(var(--space-2xl), 14vh, var(--space-4xl)); }
.legal--404 .legal__lead { text-wrap: balance; }
.legal__actions { display: flex; flex-wrap: wrap; gap: var(--space-sm); margin-block-start: var(--space-xl); }
.legal__foot { padding-block: var(--space-lg); border-block-start: var(--rule-hair) solid var(--color-rule); font-size: var(--text-sm); color: var(--color-muted); }

/* ============================================================ WhatsApp, fixed bottom-right
   A CIRCLE, the one round shape on a page of 2px corners: a floating chat
   button is recognised by its convention (round, bottom-right), and a square
   read as just another button. INK AND PAPER, not WhatsApp green (owner:
   "flashy") and not vermilion (the accent is the correction mark): the
   glyph carries the recognition. A solid 2px paper ring (owner's reference,
   2026-09-26) keeps it crisp over photographs and the night bands (carousel,
   form, footer), where plain ink would vanish; the faint ring before it
   didn't. */
.wa {
  position: fixed; z-index: var(--z-sticky);
  inset-inline-end: max(var(--space-md), env(safe-area-inset-right));
  inset-block-end: max(var(--space-md), env(safe-area-inset-bottom));
  display: grid; place-items: center;
  inline-size: 3.5rem; block-size: 3.5rem;
  border-radius: 50%;
  background: var(--color-ink); color: var(--color-paper);
  border: 2px solid var(--color-paper);
  box-shadow: 0 6px 20px oklch(20% 0.005 270 / 0.28);
  transition: transform var(--dur-short) var(--ease-out), box-shadow var(--dur-short) var(--ease-out);
}
.wa svg { inline-size: 1.8rem; block-size: 1.8rem; fill: currentColor; }
.wa:hover { transform: translateY(-2px); box-shadow: 0 10px 26px oklch(20% 0.005 270 / 0.32); }
.wa:focus-visible { outline: var(--rule-bold) solid var(--color-focus); outline-offset: 3px; }
@media (max-width: 40rem) { .wa { inline-size: 3.25rem; block-size: 3.25rem; } }
@media (prefers-reduced-motion: reduce) { .wa, .wa:hover { transition: none; transform: none; } }

/* ============================================================ surfaces: day · dusk · night
   From a study of squarespace.com and wix.com (2026-09-21). Ten of our eleven
   blocks sat on one paper, split by hairlines, so the page had no change of
   surface from top to bottom — that, not the palette, is what read as flat
   next to them. Squarespace runs black → white → black and crosses the second
   change with a long fade; Wix stays white and lifts three moments with a soft
   coloured wash. We take the rhythm and the restraint, in our own three
   colours: two night bands, one fade, two glows. Nothing else gets a surface.
   Night is done by REMAPPING the colour tokens, not by restyling components:
   everything inside .on-ink (the footer) reads the same
   token names and inverts on its own. Don't add per-component dark overrides —
   add the missing token to the remap instead. The form band is NOT .on-ink:
   it was already hand-built as paper-on-ink, and remapping would flip it. */
.on-ink {
  --color-paper:   var(--color-night-paper);
  --color-paper-2: var(--color-night-paper-2);
  --color-paper-3: var(--color-night-paper-3);
  --color-ink:     var(--color-night-ink);
  --color-ink-2:   var(--color-night-ink-2);
  --color-muted:   var(--color-night-muted);
  --color-neutral: var(--color-night-neutral);
  --color-rule:    var(--color-night-rule);
  --color-rule-2:  var(--color-night-rule-2);
  --color-accent:  var(--color-accent-light);
  --color-focus:   var(--color-accent-light);
  --color-error:   var(--color-error-night);
  background: var(--color-paper);
  color: var(--color-ink);
}



/* Glow, day: the accent at 7% behind the headline, full-bleed, fading to the
   paper well before the edges. Felt, not seen — if it reads as a colour, it is
   too strong. */
.hero { position: relative; isolation: isolate; }
.hero::before {
  content: "";
  position: absolute; z-index: -1;
  inset-block: 0;
  inset-inline: calc(50% - 50vw);
  background: radial-gradient(ellipse 55% 60% at 50% 40%, var(--color-glow-day), transparent 70%);
  pointer-events: none;
}

/* The footer is the one dark band left; with the form light again it opens
   on its own padding and hairline (the .foot base rule), not a shared band. */

/* ============================================================ one orchestrated entrance */

/* First load (2026-10-06, owner's brother: the hero appeared with a bang,
   unlike the language switch's cross-fade). Was 420ms, 10px, 70ms apart:
   over in half a second, it read as a pop. Now each piece rises 14px out of
   a slight blur over 700ms, 110ms apart (the hero film's own text move),
   done by ~1.2s. The film panel (--i 5) rises without the blur: a filter on
   that much moving picture is costly on phones. The sky, nav and icon stay
   put; fading a dark sky in from white would flash. */
/* the start lives in the keyframes (fill: backwards), so when it ends the
   element is simply itself: a forwards fill left blur(0px) on each, which
   still puts the text on its own layer */
.reveal {
  animation: reveal 700ms var(--ease-out) backwards;
  animation-delay: calc(var(--i, 0) * 110ms);
}
.hero__stage.reveal { animation-name: reveal-plain; }
@keyframes reveal { from { opacity: 0; transform: translateY(14px); filter: blur(6px); } }
@keyframes reveal-plain { from { opacity: 0; transform: translateY(14px); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 150ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 150ms !important;
  }
  .reveal, .hero__stage.reveal { animation: reveal-quiet 150ms linear backwards; }
  @keyframes reveal-quiet { from { opacity: 0; } }
  .btn:hover { transform: none; }
  /* The service deck holds still on Websites: no entrance, no cycling
     (app.js doesn't start it). */
  .deck__tile, .deck__tile::after, .deck__label { transition: none; }
}

/* ============================================================ responsive */

@media (max-width: 60rem) {
  /* Narrow: the site takes a full row, its two other states sit side by side
     under it. NOT one column with a 16/7 letterbox — that was the first attempt
     and it was wrong: these are tall portrait captures, so a wide slot crops
     them to a zoomed horizontal band and you get one enormous floating word
     instead of a page. Two portrait slots keep them legible as pages, and keep
     the section from running to three full-width images on a phone. */
  .triptych {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-md);
    margin-inline: 0; inline-size: auto;
  }
  .triptych .build__stage { order: -1; grid-column: 1 / -1; }
  /* stage spans all columns here, so the 62vw centre no longer exists and the
     annotations return to the shell edge */
  .build__figure .dip__label--after,
  .build__actions,
  .build__arrow { margin-inline-start: 0; }
  .triptych__side { aspect-ratio: 3 / 4; }
  .triptych__side--a { order: 0; }          /* undo the desktop reorder */
  .triptych__side img { object-position: 50% 50%; }
  /* --text-display is fluid and resolves to 48-64px through this range, so the
     144 default is a 2.3-3x mismatch. Desktop above 60rem keeps 144: at 64-84px
     that genuinely is a display size, which is what the default is drawn for. */
  .hero__display { --opsz: 72; }
  .ask__grid { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .form__row { grid-template-columns: minmax(0, 1fr); }
  .offer { gap: var(--space-xl); }
  .offer__cards { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-lg); inline-size: min(100%, 38rem); }
}

/* How it works below 75rem: four columns squeeze the written review under
   ~190px, where its lines wrap out of the panel. Two columns instead: the two
   moments share a row, the fortnight takes a full row, so the band keeps its
   width and each half keeps its own picture, and the sign-off is a moment
   again, one column wide (full width it was a big, near-empty box). */
@media (max-width: 75rem) {
  .track { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .tstep:nth-child(n+3) { margin-block-start: var(--space-lg); }
  .tstep--span { grid-column: 1 / -1; }
  .ctrack { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .cstep:first-child { grid-column: 1 / -1; margin-block-end: var(--space-lg); }
  .tpanel { block-size: clamp(10rem, 24vw, 13rem); }
}

/* Below 48rem a side-by-side comparison is unreadable — stack the two designs
   full-width instead, and retire the divider entirely. */
@media (max-width: 48rem) {
  .dip__pair { grid-template-columns: minmax(0, 1fr); gap: var(--space-xl); }
  /* One true desktop viewport. Stacked and unsynced, each frame is a still that
     has to read as a desktop screen by itself, so it takes the real 1.6 rather
     than the taller working ratio the scroll-synced desktop panels use. */
  .dip__frame { aspect-ratio: 16 / 10; }
  .build__figure .build__frame { aspect-ratio: 16 / 10; }   /* must match the base rule's specificity */
}

@media (max-width: 40rem) {
  /* These are figcaptions, not affordances, so wrapping is allowed — but at
     0.14em tracking a stack descriptor cannot fit 320px on one line. Tighten
     the tracking and give it a real line-height so two lines read composed. */
  .dip__label { letter-spacing: 0.06em; line-height: 1.5; }
  .dip__label--pair { letter-spacing: 0; }
  .build__name { font-size: var(--text-xl); --track: var(--track-md); }

  .band { padding-block: var(--space-2xl); }
  .band--tall { padding-block: var(--space-2xl); }
  .hero { padding-block: var(--space-xl) var(--space-2xl); }
  .head__title { font-size: var(--text-xl); --opsz: 48; --track: var(--track-md); }
  /* Fraunces' opsz is a true optical size, not a weight knob, and the h1
     default of 144 is drawn for poster use. Here the headline renders at
     36-54px, so 144 is a 3-4x mismatch and the hairlines go sub-pixel — the
     same bug class that once made the nav wordmark's `t` vanish. 54 keeps the
     ratio inside the ~1.5x the rest of the page works to. */
  .hero__display { font-size: var(--text-display-s); --track: var(--track-lg); --opsz: 54; max-width: 100%; }
  /* .btn goes inline-size:100% here, so a flex ROW of hero actions overflows.
     The secondary is a ghost BUTTON now, not a .tlink, so both need stacking. */
  .hero__actions { flex-direction: column; align-items: stretch; }
  /* How it works: one column, each drawing straight under its step. The
     fortnight keeps its two halves side by side under the two halves of the
     band, so each label still sits over its own picture. */
  .track { grid-template-columns: minmax(0, 1fr); }
  .tstep:nth-child(n+2) { margin-block-start: var(--space-lg); }
  .tpanel { block-size: clamp(9rem, 44vw, 12rem); }
  .tpanel-pair .tpanel { block-size: clamp(9rem, 50vw, 12rem); }
  .tband span { padding-inline: var(--space-xs); letter-spacing: 0.06em; }
  /* At 320 a half is ~144px and "Days 8 – 14 · Refine" needs ~160: the band
     grows to two lines, breaking only after the dot (the days are held
     together with no-break spaces in the markup). */
  .tstep__mark.tband { block-size: auto; min-block-size: 1.5rem; }
  .tband span { white-space: normal; padding-block: 0.2rem; line-height: 1.35; }
  .ctrack { grid-template-columns: minmax(0, 1fr); }
  /* Pricing on a phone: the price one size down, so "Custom quote" holds one
     line. */
  .card { padding: var(--space-lg); }
  .card__price { font-size: var(--text-2xl); }
  .cstep + .cstep { margin-block-start: var(--space-lg); }
  .cstep:first-child { margin-block-end: 0; }
  .hero__object { block-size: 128px; }
  /* Below 40rem both clauses wrap anyway, and forcing the break as well leaves
     an orphaned "premium —" on its own line. Let it flow as one paragraph. */
  .hero__lede br { display: none; }
  .deck { inline-size: 76px; block-size: 76px; }
  .ask h2 { font-size: var(--text-2xl); --track: var(--track-lg); }
  .card { padding: var(--space-lg); }
  .btn { inline-size: 100%; justify-content: center; }
  .nav__cta { inline-size: auto; }
  .nav__cta { inline-size: auto; }
}

/* ================================================= ToDesktop type (2026-09-29)
   The owner's call: their type system, measured on todesktop.com at 1280
   and 375. Aeonik Pro 500 for every heading at -1.5%, Inter for text, Geist
   Mono 11px caps for labels. Section heads are 64/72 (42/46 on phones), the
   hero 74/84 (46/54), subs 16/26 in #656565, headings in ink, not blue.
   Placed last so it outranks the per-section phone overrides above. Section
   layouts themselves are cloned later. */
.head__title, .words__title, .about__title, .faq__title, .ask h2, .legal__title {
  font-size: var(--text-section); font-weight: 500;
  --track: var(--track-lg); letter-spacing: var(--track-lg);
  --leading: 1.125; line-height: 1.125;
}
.hero__display { font-size: var(--text-display); --track: var(--track-display); --leading: var(--leading-display); }
.head__sub, .more__sub, .offer__sub, .hero__lede { font-size: var(--text-base); line-height: 1.625; color: var(--color-ink-2); }
/* Their section heads sit centred over the content. */
.head { align-items: center; text-align: center; margin-inline: auto; max-width: 56rem; }
.head__title { max-width: 20ch; }
@media (max-width: 40rem) {
  .head__title, .words__title, .about__title, .faq__title, .ask h2, .legal__title { line-height: 1.095; --leading: 1.095; }
  .hero__display { line-height: 1.174; --leading: 1.174; }
}
/* Their plan price is 48/52 Aeonik 500; their FAQ question is Inter 14/22 500. */
.card__price { font-size: var(--text-2xl); font-weight: 500; line-height: 1.083; }
.faq__q { font-size: var(--text-nav); font-weight: 500; line-height: 22px; letter-spacing: -0.01em; }

/* ================================================= hero · ToDesktop's, cloned (2026-09-29, owner)
   Measured on todesktop.com at 1280: emblem 64 · pill 24 · headline 74/84 ·
   sub 16/26 · 36px pill buttons · three step tabs (icon pill 6/18, 14/22
   text, the others at 60%) on a 1px line whose glowing fill runs under the
   steps · a 20px-radius window panel whose top shows at the fold. Their sky
   runs from #0f071d through indigo and electric blue to white; ours ends on
   the page grey. The sky reaches under the nav (the nav goes light-on-dark
   over it, app.js) and past the hero, so Redesigned opens on the fade. */
:root { --nav-h: 82px; --sky-tail: 12rem; }
.hero {
  position: relative; isolation: isolate;
  margin-block-start: calc(-1 * var(--nav-h));
  padding-block: calc(var(--nav-h) + 14px) 0;
  color: #fff;
}
.hero::before { content: none; }
/* The sky's tail runs under Redesigned; positioned, that section paints above it. */
#case { position: relative; }
.hero__sky {
  position: absolute; z-index: -1; inset-inline: 0; inset-block-start: 0;
  block-size: calc(100% + var(--sky-tail));
  pointer-events: none; overflow: hidden;
  background: linear-gradient(180deg,
    #0f071d 0%, #0f071d 13%, #13023a 24%, #070b6b 35%, #061db6 45%,
    #0a2bc8 54%, #1040e0 65%, #1450e6 76%, #1a62e8 84%, #3f8fec 89%,
    #a9d3f2 94%, #e6f1f6 97.5%, var(--color-paper) 100%);   /* deep blue under the whole stage, as theirs (2026-10-01) */
}
.hero__lines {
  position: absolute; inset-inline: 0; inset-block-start: 0; inline-size: 100%; block-size: 62%;
  fill: none; stroke: #fff; stroke-opacity: 0.07; stroke-width: 1;
  -webkit-mask-image: linear-gradient(180deg, #000 55%, transparent);
          mask-image: linear-gradient(180deg, #000 55%, transparent);
}
.hero__inner { max-inline-size: 60rem; margin-inline: auto; text-align: center; position: relative; }

/* emblem: the service deck at their 64px */
.hero__object { block-size: 70px; margin-block-end: 16px; justify-content: flex-end; }
.hero .deck { inline-size: 64px; block-size: 64px; }
.hero .deck__label { display: none; }
.hero .deck__tile[data-slot="1"] { --veil: oklch(30% 0.06 280); }
.hero .deck__tile[data-slot="2"] { --veil: oklch(22% 0.05 285); }
/* the veil keeps slot 1's colour while it fades off the arriving tile
   (owner saw a flicker, 2026-09-30): the front slot had no veil colour of
   its own, so it snapped to the light default and flashed for the fade */
.hero .deck__tile[data-slot="0"], .hero .deck__tile[data-slot="out"] { --veil: oklch(30% 0.06 280); }

/* the pill: Geist Mono 11/16 caps on white 8%, their badge shadow */
.hero__pill {
  display: inline-flex; align-items: center; gap: 2px;
  margin: 0 auto 12px; padding: 4px 8px; border-radius: 999px;
  position: relative; inset-block-start: -6px;   /* a touch up, clear of the headline's icon (owner, 2026-10-01); nothing else moves */
  background: rgb(255 255 255 / 0.08);
  box-shadow: rgb(8 1 20 / 0.03) 0 2px 2px -1px, rgb(255 255 255 / 0.04) 0 2px 8px inset,
              rgb(255 255 255 / 0.1) 0 1px 3px inset, rgb(255 255 255 / 0.12) 0 0.5px 0.5px inset;
  font-family: var(--font-mono); font-size: 11px; line-height: 16px; font-weight: 500;
  letter-spacing: 0.03em; text-transform: uppercase; color: rgb(255 255 255 / 0.88);
}
.hero__pill svg { inline-size: 16px; block-size: 16px; fill: rgb(255 255 255 / 0.88); }
/* The pill names the emblem's front tile, in step with the shuffle (it was
   the deck's caption before the clone; app.js swaps the text). */
.hero__pill-t { display: inline-block; transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out); }
.hero__pill-t.is-swap { opacity: 0; transform: translateY(3px); }

/* headline: white fading to 75%, as theirs, with the icon set in the line */
.hero__display {
  max-width: none; margin: 0 auto 12px;
  background: linear-gradient(rgb(255 255 255 / 0.9), rgb(255 255 255 / 0.75));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero__display em { color: var(--color-accent-light); -webkit-text-fill-color: var(--color-accent-light); }
/* Centred on the capitals (owner's brother, 2026-09-30: it hung low). An
   inline-grid took its baseline from the symbol inside, which sits 19% up
   the tile, so the tile dropped ~15px below the text. Now an inline-block
   with nothing in flow: its baseline is the tile's own bottom edge, and
   -0.11em puts the 0.92em tile evenly over the 0.70em capitals (0.11em
   above their tops, 0.11em below the baseline). */
.hero__icon {
  display: inline-block; position: relative; vertical-align: -0.11em;
  inline-size: 0.92em; block-size: 0.92em; margin-inline: 0.04em;
  border-radius: 24%;
  background: linear-gradient(180deg, #4f7dff, #1a45e0);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.45), inset 0 0 0 1px rgb(255 255 255 / 0.16),
              0 10px 24px -8px rgb(10 30 160 / 0.7);
}
.hero__icon svg { position: absolute; inset: 0; margin: auto; inline-size: 62%; block-size: 62%; fill: none; stroke: #fff; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.hero__icon svg circle { fill: #fff; stroke: none; }
.hero__icon .hero__icon-a { fill: rgb(255 255 255 / 0.5); stroke: none; }
.hero__lede { color: rgb(255 255 255 / 0.8); margin-block-start: 0; max-width: 44rem; text-wrap: nowrap; }
@media (max-width: 48rem) { .hero__lede { text-wrap: balance; } }
.hero__alt { margin-block-start: 14px; color: rgb(255 255 255 / 0.6); line-height: 22px; }
.hero__alt .tlink { min-height: 24px; }   /* 24px target (WCAG 2.2 minimum); the 44px box added a blank line under the buttons */
@media (min-width: 40.01rem) { .hero__lede br { display: none; } }   /* one line, as their sub */
.hero__alt .tlink { color: #fff; text-decoration-color: rgb(255 255 255 / 0.4); }
/* hover turns it the headline's "forgettable" blue (owner, 2026-09-30); the
   site's usual hover blue would sink into the sky, this one reads 7:1 */
.hero__alt .tlink:hover { color: var(--color-accent-light); text-decoration-color: var(--color-accent-light); }

/* their buttons: 36px pills, 14/500 Inter in a white-to-80% fill */
.hero__actions { gap: 16px; margin-block-start: 28px; }
.hbtn {
  display: inline-flex; align-items: center; gap: 4px;
  block-size: 36px; padding: 7px 16px 7px 14px; border-radius: 999px;
  font: 500 14px/22px var(--font-body); color: #fff; text-decoration: none; white-space: nowrap;
  transition: background-color 200ms var(--ease-out), transform 50ms;
}
.hbtn:active { transform: translateY(1px); }
.hbtn span { background: linear-gradient(#fff, rgb(255 255 255 / 0.8)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hbtn svg { inline-size: 16px; block-size: 16px; fill: none; stroke: #fff; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.hbtn--primary {
  padding-inline-end: 10px;
  background: color(display-p3 0.0118 0.2067 0.9861);
  box-shadow: rgb(255 255 255 / 0.12) 0 1px 2px -0.5px inset, rgb(255 255 255 / 0.16) 0 0.5px 0.5px inset,
              rgb(255 255 255 / 0.16) 0 8px 24px -4px inset, rgb(9 1 20 / 0.03) 0 8px 8px -3px,
              rgb(8 1 20 / 0.03) 0 3px 3px -1.5px;
}
.hbtn--primary:hover { background: color(display-p3 0.1 0.3 1); }
.hbtn--dark {
  background: rgb(255 255 255 / 0.04);
  box-shadow: rgb(255 255 255 / 0.08) 0 -4px 12px -4px inset, rgb(255 255 255 / 0.06) 0 1px 3px inset,
              rgb(255 255 255 / 0.12) 0 0.5px 0.5px inset, rgb(9 1 20 / 0.06) 0 8px 8px -3px;
}
.hbtn--dark:hover { background: rgb(255 255 255 / 0.09); }
.hbtn:focus-visible { outline: 2px solid #fff; outline-offset: 3px; border-radius: 999px; }

/* the stage: tabs, line, panel — their 968px column */
.hero__stage { max-inline-size: calc(968px + 2 * var(--page-gutter)); margin-block-start: 36px; }
.steps { display: flex; align-items: flex-start; margin-block-end: 20px; }
.steps__tab {
  flex: 1; position: relative; padding: 16px 20px; border: 0; background: none; cursor: pointer;
  text-align: center; color: #fff; font: inherit;
}
.steps__tab + .steps__tab::before {   /* their hairline between steps */
  content: ""; position: absolute; inset-inline-start: 0; inset-block: 44px 20px;
  inline-size: 1px; background: rgb(255 255 255 / 0.1);
}
.steps__tab:active { transform: translateY(1px); }
.steps__icon {
  position: relative; display: block; inline-size: max-content; margin: 0 auto 16px;
  padding: 6px 18px; border-radius: 999px; box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.08);
}
.steps__icon::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; opacity: 0;
  background: linear-gradient(rgb(255 255 255 / 0.08), rgb(255 255 255 / 0.04)), rgb(255 255 255 / 0.04);
  box-shadow: rgb(9 1 20 / 0.06) 0 8px 8px -3px, rgb(8 1 20 / 0.04) 0 2px 2px -1px, rgb(255 255 255 / 0.08) 0 8px 12px -4px inset;
  transition: opacity 450ms cubic-bezier(0.6, 0.6, 0, 1);
}
.steps__tab[aria-selected="true"] .steps__icon::after { opacity: 1; }
.steps__icon svg {
  position: relative; z-index: 1; display: block; inline-size: 24px; block-size: 24px;
  fill: none; stroke: #fff; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round;
  opacity: 0.64; transition: opacity 200ms;
}
.steps__tab:hover .steps__icon svg, .steps__tab[aria-selected="true"] .steps__icon svg { opacity: 0.9; }
.steps__text { display: block; opacity: 0.6; transition: opacity 450ms cubic-bezier(0.6, 0.6, 0, 1); }
.steps__tab:hover .steps__text { opacity: 0.9; }
.steps__tab[aria-selected="true"] .steps__text { opacity: 1; }
.steps__t {
  display: block; margin-block-end: 4px; font: 500 14px/22px var(--font-body); letter-spacing: -0.01em;
  background: linear-gradient(#fff, rgb(255 255 255 / 0.8)); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.steps__d { display: block; font-size: 14px; line-height: 22px; color: rgb(255 255 255 / 0.6); text-wrap: balance; }
.steps__tab:focus-visible { outline: 2px solid #fff; outline-offset: -2px; border-radius: 16px; }
.steps__now { display: none; }
.steps__track {
  position: relative; block-size: 1px; margin: 0 auto 32px; max-inline-size: calc(100% - 64px);
  background: rgb(255 255 255 / 0.1);
}
.steps__fill {
  position: absolute; inset-block: 0; inset-inline-start: 0; inline-size: 0;
  background: rgb(255 255 255 / 0.9);
  box-shadow: rgb(255 255 255 / 0.72) 0 0 16px, rgb(255 255 255 / 0.32) 0 0 12px, rgb(255 255 255 / 0.32) 0 0 6px, rgb(255 255 255 / 0.32) 0 0 2px;
}

/* the panel: a browser window playing Ayah Kutub before → rebuild → live */
.shot {
  position: relative; border-radius: 20px; overflow: hidden;
  background: rgb(255 255 255 / 0.1);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.14), 0 40px 80px -30px rgb(4 8 60 / 0.6);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  container-type: inline-size;
}
.shot__bar {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  block-size: 40px; padding-inline: 20px;
  font: 500 12px/20px var(--font-body); color: rgb(255 255 255 / 0.56);
}
.shot__dots { display: flex; gap: 7px; }
.shot__dots i { inline-size: 10px; block-size: 10px; border-radius: 50%; background: rgb(255 255 255 / 0.22); }
.shot__url {
  padding: 2px 12px; border-radius: 8px; background: rgb(255 255 255 / 0.08);
  font-family: var(--font-mono); font-size: 11px; color: rgb(255 255 255 / 0.72);
  min-inline-size: 12rem; text-align: center; transition: opacity 300ms;
}
.shot__state { justify-self: end; display: inline-flex; align-items: center; gap: 6px; }
.shot[data-step="2"] .shot__state::before {
  content: ""; inline-size: 7px; block-size: 7px; border-radius: 50%;
  background: #3ddc84; box-shadow: 0 0 8px #3ddc84;
}
.shot__view {
  position: relative; aspect-ratio: 16 / 10; overflow: hidden;
  margin-inline: 8px; margin-block-end: 8px; border-radius: 12px; background: #fff;
}
.shot__img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; object-position: top; display: block; }
/* rebuild: the new page wipes in from the right over the old, a lit seam at its edge */
.shot__after { position: absolute; inset: 0; clip-path: inset(0 0 0 100%); transition: clip-path 1800ms cubic-bezier(0.65, 0, 0.35, 1); }
.shot[data-step="1"] .shot__after, .shot[data-step="2"] .shot__after { clip-path: inset(0 0 0 0); }
.shot__seam {
  position: absolute; inset-block: 0; inset-inline-start: 100%; inline-size: 2px; opacity: 0;
  background: #fff; box-shadow: 0 0 18px 4px rgb(120 170 255 / 0.9);
  transition: inset-inline-start 1800ms cubic-bezier(0.65, 0, 0.35, 1), opacity 400ms;
}
.shot[data-step="1"] .shot__seam { inset-inline-start: 0; opacity: 1; }
.shot[data-step="2"] .shot__seam { inset-inline-start: 0; opacity: 0; transition: none; }
.shot__day {
  position: absolute; inset-block-start: 3cqi; left: 50%; translate: -50% -6px; opacity: 0;
  padding: 5px 12px; border-radius: 999px; background: rgb(12 14 40 / 0.78); color: #fff;
  font: 500 11px/16px var(--font-mono); letter-spacing: 0.03em; text-transform: uppercase;
  transition: opacity 300ms, translate 300ms var(--ease-out);
}
.shot[data-step="1"] .shot__day { opacity: 1; translate: -50% 0; transition-delay: 200ms; }
/* audit notes: numbered pins with a label, polite and factual */
.shot__notes { position: absolute; inset: 0; margin: 0; padding: 0; pointer-events: none; }
.shot__note {
  position: absolute; display: flex; align-items: center; gap: 6px;
  translate: -12px -50%; opacity: 0; scale: 0.9; transform-origin: left center;
  transition: opacity 280ms var(--ease-out), scale 380ms cubic-bezier(0.34, 1.4, 0.5, 1);
}
.shot__note b {
  display: grid; place-items: center; inline-size: 22px; block-size: 22px; flex: none; border-radius: 50%;
  background: var(--color-accent); color: #fff; font: 600 11px/1 var(--font-body);
  box-shadow: 0 0 0 3px rgb(52 83 211 / 0.25);
}
.shot__note span {
  padding: 4px 10px; border-radius: 999px; background: #fff; color: #141414;
  font: 500 12px/18px var(--font-body); white-space: nowrap;
  box-shadow: 0 6px 16px -6px rgb(0 0 0 / 0.35), 0 0 0 0.5px rgb(0 0 0 / 0.08);
}
.shot__note.is-flip { flex-direction: row-reverse; translate: calc(-100% + 12px) -50%; transform-origin: right center; }
.shot[data-step="0"] .shot__note { opacity: 1; scale: 1; transition-delay: calc(300ms + var(--n) * 180ms); }
/* the way down to the proof */
.rig { position: relative; }
/* centred with physical left (2026-10-05): inset-inline-start is the right
   edge in Arabic, so with the -50% translate it sat 115px off to the left.
   The same for every "start: 50% + translate -50%" here (island, home bar…) */
.shot__compare {
  position: absolute; z-index: 3; left: 50%; inset-block-end: -12px; transform: translate(-50%, 50%); opacity: 0; translate: 0 8px; pointer-events: none;
  padding: 7px 14px; border-radius: 999px; background: #fff; color: #141414; text-decoration: none;
  font: 500 14px/22px var(--font-body); box-shadow: 0 10px 30px -10px rgb(0 0 0 / 0.5);
  transition: opacity 300ms, translate 300ms var(--ease-out);
}
.shot[data-step="2"] ~ .shot__compare { opacity: 1; translate: 0 0; pointer-events: auto; transition-delay: 450ms; }
.shot__compare:hover { background: #f1f1f1; }

/* ToDesktop's thin frame (owner, 2026-10-01, measured on theirs): a line
   12px outside the panel down both sides, from 52px below its top, round
   its foot 12px under it (32px corners), white at 10%; its tops fade up
   into the sky. The way down to the proof sits on its foot, so the stage
   keeps its whole height. Their lines running on into the next section
   were tried and removed the same day (owner): ours would cross the sky's
   blue-to-paper fade and change colour along their length. */
.rig__ring { display: none; }
@media (min-width: 40.0625rem) {
  .hero__stage { padding-block-end: 32px; }
  .rig__ring {
    display: block; position: absolute; inset: 52px -12px -12px; pointer-events: none;
    border: 1px solid rgb(255 255 255 / 0.1); border-block-start: 0; border-radius: 0 0 32px 32px;
    -webkit-mask: linear-gradient(transparent, #000 120px); mask: linear-gradient(transparent, #000 120px);
  }
}
@media (max-width: 40rem) { .hero__stage { padding-block-end: 24px; } }

/* the nav, while it sits on the sky */
.nav { transition: border-color var(--dur-short) var(--ease-out), background-color var(--dur-short) var(--ease-out); }
.nav[data-tone="dark"] { background: transparent; backdrop-filter: none; border-block-end-color: transparent; }
.nav[data-tone="dark"] .wordmark { color: #fff; }
.nav[data-tone="dark"] .nav__links { background: rgb(255 255 255 / 0.06); box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.08); }
.nav[data-tone="dark"] .nav__link { color: rgb(255 255 255 / 0.72); }
.nav[data-tone="dark"] .nav__link:hover { color: #fff; background: rgb(255 255 255 / 0.08); }

@media (prefers-reduced-motion: reduce) {
  .shot__after, .shot__seam, .shot__note, .shot__compare, .shot__day { transition: none !important; }
}
/* tablets: titles only, as theirs */
@media (max-width: 48rem) {
  .steps__d { display: none; }
  .steps__tab { padding-inline: 8px; }
}
/* phones: the three icons in one pill row, the active step written under it */
@media (max-width: 40rem) {
  :root { --nav-h: 68px; --sky-tail: 8rem; }
  .hero__stage { margin-block-start: 40px; }
  .hero__actions { flex-direction: row; gap: 8px; }
  .hbtn { flex: 1; justify-content: center; block-size: 46px; }
  .steps { gap: 6px; padding: 4px; border-radius: 999px; box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.08); margin-block-end: 0; }
  .steps__tab { padding: 0; }
  .steps__tab + .steps__tab::before { content: none; }
  .steps__icon { inline-size: auto; margin: 0; padding: 10px 18px; box-shadow: none; }
  .steps__icon svg { margin-inline: auto; }
  .steps__text { display: none; }
  .steps__now { display: block; padding: 12px; margin-block-end: 12px; text-align: center; }
  .steps__now .steps__d { display: block; }
  .steps__track { margin-block-end: 20px; }
  .shot { border-radius: 14px; }
  .shot__bar { block-size: 32px; padding-inline: 12px; }
  .shot__url { min-inline-size: 0; font-size: 10px; }
  .shot__view { margin-inline: 5px; margin-block-end: 5px; border-radius: 9px; }
  .shot__note span { display: none; }   /* too small to read on a phone: the pins alone mark the spots */
  .shot__note b { inline-size: 16px; block-size: 16px; font-size: 9px; }
  .shot__day { font-size: 9px; padding: 3px 8px; }
  .shot__compare { font-size: 12px; padding: 4px 10px; line-height: 18px; }
}

/* ================================================= site-wide details from ToDesktop (2026-09-29)
   1 · Buttons. Their family, measured: primary is a blue pill with inset
   light and a soft stack of drop shadows; "light" is a 96% white pill with a
   hairline ring. 14/22 500 Inter. 36px in bars and heroes, 48px as a
   full-width card or form button. .btn is now their primary, .btn--ghost
   their light. The hero's .hbtn are the same buttons on the dark sky. */
.btn {
  --btn-bg: color(display-p3 0.0118 0.2067 0.9861);
  --btn-fg: #fff;
  min-height: 36px; padding: 7px 16px; gap: 4px;
  border: 0; border-radius: 999px;
  font-size: 14px; line-height: 22px; font-weight: 500; letter-spacing: 0;
  box-shadow: rgb(255 255 255 / 0.12) 0 1px 2px -0.5px inset, rgb(255 255 255 / 0.16) 0 0.5px 0.5px inset,
              rgb(255 255 255 / 0.16) 0 8px 24px -4px inset, rgb(9 1 20 / 0.03) 0 8px 8px -3px,
              rgb(9 1 20 / 0.03) 0 5px 5px -2.5px, rgb(8 1 20 / 0.03) 0 3px 3px -1.5px,
              rgb(8 1 20 / 0.03) 0 1px 1px -0.5px;
  transition: background-color 200ms var(--ease-out), box-shadow 200ms var(--ease-out), transform 50ms;
}
.btn:hover { --btn-bg: color(display-p3 0.1 0.3 1); transform: none; }
.btn:active { transform: translateY(1px); }
.btn--ghost {
  --btn-bg: rgb(255 255 255 / 0.96); --btn-fg: #141414;
  box-shadow: rgb(0 0 0 / 0.04) 0 8px 8px -3px, rgb(0 0 0 / 0.04) 0 3px 3px -1.5px,
              rgb(0 0 0 / 0.03) 0 1px 1px -0.5px, rgb(0 0 0 / 0.04) 0 0 0 1px;
}
.btn--ghost:hover { --btn-bg: #fff; --btn-fg: #141414; }
.card__cta, .form__submit { min-height: 48px; padding: 13px 20px; justify-content: center; }
.btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; border-radius: 999px; }

/* 2 · The pill above every section heading: Geist Mono 11/16 caps, #656565
   on a 4% grey pill, 24px tall, as their FEATURES / PRICING labels. */
.eyebrow {
  display: inline-block; inline-size: max-content; margin: 0 0 16px; padding: 4px 14px; border-radius: 999px;
  background: var(--t-well);
  font-family: var(--font-mono); font-size: 11px; line-height: 16px; font-weight: 500;
  letter-spacing: 0.03em; text-transform: uppercase; color: var(--color-ink-2);
}
.head .eyebrow, .words__lede .eyebrow { margin-block-end: 4px; }   /* those heads already space their children */
.faq__head { min-width: 0; }

/* 3 · The nav once it leaves the sky: their floating pill. The bar keeps its
   height (it is sticky in flow, so a change would shift the page); inside
   it the row narrows to a 41rem white pill, 88% with a 12px blur and their
   three-layer shadow. Over the sky it stays the full-width transparent bar. */
.nav { block-size: var(--nav-h); background: transparent; backdrop-filter: none; border-block-end: 0; }
.nav__inner {
  max-inline-size: 84rem; margin-block-start: 0; padding-block: 0; block-size: 100%;
  border-radius: 999px;
  transition: max-inline-size 450ms cubic-bezier(0.6, 0.6, 0, 1), background-color 300ms, box-shadow 300ms,
              padding 450ms cubic-bezier(0.6, 0.6, 0, 1), margin 450ms cubic-bezier(0.6, 0.6, 0, 1), block-size 450ms cubic-bezier(0.6, 0.6, 0, 1);
}
.nav[data-tone="light"] .nav__inner {
  max-inline-size: 41rem; block-size: 60px; margin-block-start: 11px;
  padding: 12px 12px 12px 18px;
  background: var(--t-pill);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  box-shadow: rgb(0 0 0 / 0.08) 0 1px 2px, rgb(0 0 0 / 0.08) 0 4px 16px, rgb(0 0 0 / 0.08) 0 16px 56px;
}
.nav[data-tone="light"] .nav__links { background: transparent; box-shadow: none; padding: 0; }
.nav[data-tone="light"] .wordmark { font-size: 1.25rem; }
.nav .nav__cta { min-height: 36px; padding: 7px 16px; }
.nav[data-tone="dark"] .nav__cta { box-shadow: none; }
@media (max-width: 40rem) {
  .nav[data-tone="light"] .nav__inner { max-inline-size: calc(100% - 2 * 12px); block-size: 56px; margin-block-start: 6px; padding: 10px 10px 10px 16px; }
}

/* ================================================= Redesigned · ToDesktop's customer dock (2026-09-29, owner)
   Their dock, measured: a 24px-radius glass bar, 6px padding, 72px icons
   3px apart, pulled 100px up over the screen; each icon's name rises above
   it on hover, blurred 4px and scaled 0.9 until then. Ours holds the two
   cases and a last slot for the visitor's own site. On our grey it's the
   night glass of the hero, so it reads as the same object. The handwritten
   notes stand in for their script images, desktop only. */
.dock-wrap { position: relative; display: flex; justify-content: center; margin-block: -40px 8px; z-index: 3; }

.dock {
  display: flex; align-items: flex-end; gap: 3px; padding: 6px; border-radius: 24px;
  background: linear-gradient(rgb(255 255 255 / 0.06), rgb(255 255 255 / 0)), rgb(12 12 32 / 0.82);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  box-shadow: rgb(255 255 255 / 0.06) 0 1px 3px inset, rgb(255 255 255 / 0.06) 0 0.5px 0.5px inset,
              rgb(2 9 44 / 0.24) 0 16px 56px, rgb(1 9 44 / 0.24) 0 4px 16px, rgb(2 9 44 / 0.24) 0 1px 2px;
}
.dock__item {
  position: relative; display: grid; place-items: center; inline-size: 72px; block-size: 72px;
  padding: 0; border: 0; border-radius: 18px; background: #fff; cursor: pointer; color: #fff; text-decoration: none;
  transition: transform 200ms cubic-bezier(0.34, 1.4, 0.5, 1);
}
.dock__item img { inline-size: 62%; block-size: 62%; object-fit: contain; }
.dock__item:hover { transform: translateY(-4px); }
.dock__item[aria-selected="true"]::after {   /* the dock's running-app dot */
  content: ""; position: absolute; inset-block-end: -5px; inline-size: 4px; block-size: 4px; border-radius: 50%;
  background: rgb(255 255 255 / 0.85);
}
/* the divider between the redesigns and the rest (EuroDecor, your site),
   as the macOS dock separates apps from folders */
.dock__sep { align-self: center; inline-size: 1px; block-size: 56px; margin-inline: 6px; background: rgb(255 255 255 / 0.18); }
/* the dock's one turn (app.js dockSpin, 2026-10-06): it clips sideways
   while the icons go round, its shadow moves to a plate behind (the clip
   would cut it square), and the copies that close the lap sit on the
   icons' own spots */
.dock { position: relative; }
.dock.is-spinning {
  perspective: 700px; clip-path: inset(-30px 0 -30px 0 round 24px);
  box-shadow: rgb(255 255 255 / 0.06) 0 1px 3px inset, rgb(255 255 255 / 0.06) 0 0.5px 0.5px inset;
}
.dock.is-spinning > * { pointer-events: none; backface-visibility: hidden; }
.dock__plate { position: absolute; z-index: -1; pointer-events: none; }
.dock__ghost { position: absolute; margin: 0; }
.dock__item--you { background: rgb(255 255 255 / 0.06); box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.16); }
.dock__item--you svg { inline-size: 26px; block-size: 26px; fill: none; stroke: rgb(255 255 255 / 0.7); stroke-width: 1.6; stroke-linecap: round; }
.dock__tip {
  position: absolute; inset-block-end: calc(100% + 12px); left: 50%; translate: -50% 0;   /* physical left: in Arabic inset-inline-start is the right edge, and the -50% pushed the label off to the left */
  padding: 4px 14px; border-radius: 6px; white-space: nowrap; pointer-events: none;
  font: 400 14px/22px var(--font-body); color: #fff;
  background: linear-gradient(rgb(255 255 255 / 0.06), rgb(255 255 255 / 0)), rgb(5 6 27 / 0.86);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  box-shadow: rgb(255 255 255 / 0.06) 0 1px 3px inset, rgb(1 9 44 / 0.24) 0 4px 8px, 0 0 0 1px #192e4e;
  opacity: 0; scale: 0.9; filter: blur(4px);
  transition: opacity 200ms, scale 200ms, filter 200ms;
}
.dock__sub { color: rgb(255 255 255 / 0.6); }
.dock__item:hover .dock__tip, .dock__item:focus-visible .dock__tip { opacity: 1; scale: 1; filter: none; }
.dock__item:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; }
/* the "+" asks first (app.js dockYou): the first click or tap keeps the
   label up and turns it into what the next one does; the label is part of
   the link, so clicking it goes to the form */
.dock__tip-b { display: none; }
.dock__item--you.is-armed .dock__tip { display: block; opacity: 1; scale: 1; filter: none; pointer-events: auto; }
.dock__item--you.is-armed .dock__tip-a { display: none; }
.dock__item--you.is-armed .dock__tip-b { display: inline; }

/* handwritten notes with drawn arrows */
.hand {
  position: absolute; margin: 0; display: flex; align-items: flex-end; gap: 4px; pointer-events: none;
  font-family: "Caveat", "Bradley Hand", "Segoe Print", "Comic Sans MS", cursive;
  font-size: 27px; line-height: 1; color: var(--color-ink-2); white-space: nowrap;   /* Caveat runs small: 27px reads as the 22px it replaced */
}
.hand svg { fill: none; stroke: var(--color-ink-2); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.hand--dock { inset-inline-end: calc(50% + 130px); inset-block-start: 40px; }
.hand--dock svg, .hand--click svg { inline-size: 80px; block-size: 44px; }
.hand--dock span { margin-block-end: 2px; }
.hand--click { inset-inline-start: calc(50% + 130px); inset-block-start: 40px; }
.hand--sync { inset-inline-end: -10px; inset-block-start: -66px; flex-direction: column; align-items: flex-end; }
.hand--sync svg { inline-size: 110px; block-size: 80px; margin-inline-end: 20px; }
.dip__pair { overflow: visible; }
@media (max-width: 70rem) { .hand { display: none; } }
@media (max-width: 40rem) {
  .dock-wrap { margin-block-start: -26px; }   /* overlaps the frame's foot by ~40% of the 62px dock, as on desktop and theirs (2026-09-29; it floated 16px below) */
  /* the hint row (owner, 2026-09-29): "2 cases · Next" wrapped onto a third
     line by itself, flush right. Now the hint takes its own line and the two
     actions share the next one, one at each end. */
  .dip__hint { row-gap: 4px; }
  .dip__hint-a { flex-basis: 100%; }
  .dock { border-radius: 16px; padding: 5px; }
  .dock__item { inline-size: 52px; block-size: 52px; border-radius: 13px; }
  .dock__sep { block-size: 38px; margin-inline: 4px; }
  .dock.is-spinning { clip-path: inset(-30px 0 -30px 0 round 16px); }
  .dock__tip { display: none; }
}
/* under 360px both links don't fit one row: "Next: Ayah Kutub →" already
   says there is another case, so the count goes */
@media (max-width: 22.5rem) { .dip__count { display: none; } }

/* Redesigned fits one screen (2026-09-29, owner): the sector line is gone,
   the gaps are tighter, and on desktop the frames take whatever height the
   window leaves (never flatter than 5:3, never taller than the old 7:6 shape),
   so eyebrow to scrubber is in view once you arrive at the section. The
   panels were a locked 7:6; app.js scales each frame to its panel, so any
   shape works. */
#case.band { padding-block-start: 40px; }
#case .dip { margin-block-start: 28px; }
#case .dip__controls { margin-block-start: 12px; }
#case .dip__hint .tlink { min-height: 28px; }
@media (min-width: 60.01rem) {
  /* Floor: a 5:3 window (60% of its width). On short screens the whole
     section can't fit without letterboxing the sites (owner, 2026-09-29:
     "feels very tight"), so there the scrubber row sits just below the fold
     instead. Ceiling: the old 7:6. */
  #case .dip__half { container-type: inline-size; }
  #case .dip__frame { aspect-ratio: auto; block-size: clamp(60cqi, calc(100svh - 545px), 117cqi); }
}

/* ================================================= How it works · ToDesktop's icon grid (2026-09-29, owner)
   Measured: a 960px grid of three 312px columns, each item 32/18/32/32
   padded, a 22px line icon 12px from the text, a 14/22 500 ink lead-in run
   into a 14/22 #656565 line; hairlines at 6% ink between rows and columns. */
.incl {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  max-inline-size: 960px; margin: 48px auto 0; padding: 0 12px; list-style: none;
}
.incl__item { display: flex; gap: 12px; padding: 32px 18px 32px 32px; border-color: var(--t-line); border-style: solid; border-width: 0; }
.incl__item:nth-child(-n+3) { border-block-end-width: 1px; }
.incl__item:not(:nth-child(3n+1)) { border-inline-start-width: 1px; }
.incl__item svg {
  flex: none; inline-size: 22px; block-size: 22px;
  fill: none; stroke: var(--color-ink); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}
.incl__item p { margin: -1px 0 0; font-size: 14px; line-height: 22px; color: var(--color-ink-2); }
.incl__item b { font-weight: 500; color: var(--color-ink); margin-inline-end: 4px; }
@media (min-width: 40.01rem) and (max-width: 60rem) {
  .incl { grid-template-columns: repeat(2, minmax(0, 1fr)); max-inline-size: 640px; }
  .incl__item { border-width: 0 !important; }
  .incl__item:nth-child(-n+4) { border-block-end-width: 1px !important; }
  .incl__item:nth-child(even) { border-inline-start-width: 1px !important; }
}
@media (max-width: 40rem) {
  .incl { grid-template-columns: minmax(0, 1fr); max-inline-size: 480px; margin-block-start: 24px; }
  .incl__item { border-width: 0 !important; padding: 24px 12px; }
  .incl__item + .incl__item { border-block-start-width: 1px !important; }
}
/* the two tracks: ToDesktop's Monthly / Yearly control, measured: a 4% grey
   well, 10px radius, 3px padding; a white pill (6px radius, their soft
   four-layer shadow) slides under the chosen side; 14px labels 10/12
   padded, the chosen one 500 ink, the other #656565. Opens on Website
   transformation; the page reads complete without touching it. */
.seg {
  position: relative; display: grid; grid-template-columns: 1fr 1fr; inline-size: max-content;
  margin: 32px auto 0; padding: 3px; border-radius: 10px; background: var(--t-well-2);
}
.seg__pill {
  position: absolute; inset-block: 3px; inset-inline-start: 3px; inline-size: calc(50% - 3px);
  border-radius: 6px; background: #fff;
  box-shadow: 0 1px 1px -0.5px rgb(0 0 0 / 0.03), 0 3px 3px -1.5px rgb(0 0 0 / 0.02), 0 6px 6px -3px rgb(0 0 0 / 0.04), 0 12px 12px -3px rgb(0 0 0 / 0.06);
  transition: translate 300ms ease-in-out;
}
.seg[data-on="1"] .seg__pill { translate: 100% 0; }
.seg__opt {
  position: relative; z-index: 1; min-inline-size: 180px; padding: 10px 12px; border: 0; border-radius: 6px;
  background: none; cursor: pointer; font: 400 14px/20px var(--font-body); color: var(--color-ink-2);
  transition: color 300ms;
}
.seg__opt[aria-selected="true"] { font-weight: 500; color: var(--color-ink); }
.seg__opt:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.incl[hidden] { display: none; }
#process .incl { margin-block-start: 24px; }
@media (max-width: 40rem) {
  .seg { max-inline-size: 100%; }
  .seg__opt { min-inline-size: 0; padding-inline: 8px; font-size: 13px; white-space: nowrap; }
}
/* "It switches": the first time the toggle comes into view the pill leans
   toward Custom builds twice and settles, and the label brightens as it
   does; a hover on the unchosen side makes the pill lean the same way.
   Once touched, never again. No motion under reduced motion. */
@keyframes seg-peek { 0%, 100% { translate: 0 0; } 22%, 62% { translate: 14% 0; } 42% { translate: 0 0; } }
@keyframes seg-peek-t { 0%, 100% { color: var(--color-ink-2); } 22%, 62% { color: var(--color-ink); } }
.seg.is-hint .seg__pill { animation: seg-peek 1600ms cubic-bezier(0.45, 0, 0.25, 1); }
.seg.is-hint .seg__opt[aria-selected="false"] { animation: seg-peek-t 1600ms cubic-bezier(0.45, 0, 0.25, 1); }
.seg:not([data-on="1"]):has(.seg__opt[aria-selected="false"]:hover) .seg__pill { translate: 6% 0; }
.seg[data-on="1"]:has(.seg__opt[aria-selected="false"]:hover) .seg__pill { translate: 94% 0; }
.seg__opt[aria-selected="false"]:hover { color: var(--color-ink); }
@media (prefers-reduced-motion: reduce) {
  .seg.is-hint .seg__pill, .seg.is-hint .seg__opt { animation: none; }
}

/* ================================================= Pricing · ToDesktop's, cloned (2026-09-29, owner)
   Measured at 1280: 360px cards 24px apart; a 4% grey well (24px radius,
   4px padding) holding a white 88% name panel (20px radius, 32/36/36, their
   soft shadow) with a 24/32 Aeonik title and a 14/22 grey line; under it,
   36px in: the 48/52 price with a 14/22 unit, a 48px button, a dashed 12%
   rule 31px either side, an 11/16 mono label and a list of 22px icons at
   #a4a4a4 beside 14/22 text with a 500 ink lead. The dark card is #141414
   with a white 8% name panel and inset light; its text runs 88% / #999.
   Under both, their Enterprise row: one well, a name panel a third wide, a
   two-column list. */
.pgrid { display: grid; grid-template-columns: repeat(2, 360px); gap: 24px; justify-content: center; margin-block-start: 56px; }
.pcard { border-radius: 24px; padding: 4px; background: var(--t-well); display: flex; flex-direction: column; }
.pcard__name {
  margin-block-end: 32px; padding: 32px 36px 36px; border-radius: 20px; background: var(--t-panel);
  box-shadow: rgb(0 0 0 / 0.02) 0 6px 6px -3px, rgb(0 0 0 / 0.02) 0 3px 3px -1.5px, rgb(0 0 0 / 0.03) 0 1px 1px -0.5px, rgb(0 0 0 / 0.04) 0 12px 12px -3px;
}
.pcard__t { margin: 0 0 12px; font: 500 24px/32px var(--font-display); letter-spacing: -0.01em; color: var(--t-ink); }
.pcard__d { margin: 0; font-size: 14px; line-height: 22px; color: var(--t-ink-2); }
.pcard__body { padding: 0 36px 36px; display: flex; flex-direction: column; flex: 1; }
.pcard__price { display: flex; align-items: flex-end; gap: 9px; margin: 0 0 16px; }
.pcard__num { font: 500 48px/52px var(--font-display); letter-spacing: -0.015em; color: var(--t-ink); white-space: nowrap; }
.pcard__unit { margin-block-end: 8px; font-size: 14px; line-height: 22px; color: var(--t-ink-2); }
.pcard__note { margin: 0 0 24px; font-size: 14px; line-height: 22px; color: var(--t-ink-2); }
.pcard__note b { display: block; margin-block-start: 8px; font-weight: 500; color: var(--t-ink); }
.pcard .card__cta, .prow .card__cta { inline-size: 100%; }
.pcard__rule { display: block; inline-size: 100%; block-size: 2px; margin: 31px 0; stroke: var(--t-dash); stroke-width: 1; stroke-dasharray: 4 4; }
.pcard__k { margin: 0 0 24px; font: 500 11px/16px var(--font-mono); letter-spacing: 0.03em; text-transform: uppercase; color: var(--t-ink-2); }
.pcard__list { display: flex; flex-direction: column; gap: 16px; margin: 0; padding: 0; list-style: none; }
.pcard__list li { display: flex; gap: 12px; }
.pcard__list svg { flex: none; inline-size: 22px; block-size: 22px; fill: none; stroke: var(--t-ghost); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.pcard__list span { font-size: 14px; line-height: 22px; color: var(--t-ink-2); }
.pcard__list b { font-weight: 500; letter-spacing: -0.01em; color: var(--t-ink); }
/* the dark card */
.pcard--dark { background: #141414; }
.pcard--dark .pcard__name {
  background: rgb(255 255 255 / 0.08);
  box-shadow: rgb(255 255 255 / 0.04) 0 4px 8px inset, rgb(255 255 255 / 0.04) 0 2px 4px inset, rgb(255 255 255 / 0.04) 0 1px 1px inset, rgb(255 255 255 / 0.06) 0 0.5px 0.5px inset;
}
.pcard--dark .pcard__t, .pcard--dark .pcard__num, .pcard--dark .pcard__note b, .pcard--dark .pcard__list b { color: rgb(255 255 255 / 0.88); }
.pcard--dark .pcard__d, .pcard--dark .pcard__unit, .pcard--dark .pcard__note, .pcard--dark .pcard__k { color: #a4a4a4; }
.pcard--dark .pcard__list span { color: #999; }
.pcard--dark .pcard__list svg { stroke: #707070; }
.pcard--dark .pcard__rule { stroke: rgb(255 255 255 / 0.12); }
.pcard--dark .btn:focus-visible { outline-color: #fff; }
/* their gray button (Contact sales) */
.btn--gray {
  --btn-bg: #333; --btn-fg: #fff;
  box-shadow: rgb(255 255 255 / 0.36) 0 1px 2px -0.5px inset, rgb(255 255 255 / 0.18) 0 0.5px 0.5px inset,
              rgb(255 255 255 / 0.25) 0 8px 24px -4px inset, rgb(0 0 0 / 0.1) 0 8px 8px -3px,
              rgb(0 0 0 / 0.1) 0 3px 3px -1.5px, rgb(0 0 0 / 0.06) 0 1px 1px -0.5px;
}
.btn--gray:hover { --btn-bg: #3d3d3d; }
/* the wide row */
.prow {
  display: flex; gap: 24px; align-items: center; max-inline-size: calc(2 * 360px + 24px); margin: 24px auto 0;
  padding: 4px; border-radius: 20px; background: var(--t-well);
}
.prow__name { flex: 0 0 calc(33.333% + 60px); margin: 0; border-radius: 18px; }
.prow__name .pcard__d { margin-block-end: 24px; }
.prow__list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 12px; flex: 1; padding: 24px 24px 24px 0; }
@media (max-width: 48rem) {
  .pgrid { grid-template-columns: minmax(0, 360px); margin-block-start: 36px; gap: 16px; }
  .prow { flex-direction: column; align-items: stretch; max-inline-size: 360px; gap: 0; }
  .prow__list { grid-template-columns: minmax(0, 1fr); padding: 28px 32px 32px; }
}

/* ================================================= FAQ · ToDesktop's, cloned (2026-09-29, owner)
   Measured: the heading centred, 64px above two flex columns (952px max,
   16px apart, 14px padding); each question its own box, 1px 6% ink, 14px
   radius; the question 14/22 500 ink at -0.14px, padded 23/15/18/23 with a
   24px chevron; the answer 14/22 grey, padded 0/16/23/23, its height eased
   0.45s (their curve). Under it: "More questions?" with two 4% grey chip
   links. */
.faq { display: block; }
.faq__head { display: flex; flex-direction: column; align-items: center; text-align: center; margin-block-end: 64px; }
.faq__title { max-width: none; }
.faq__list { display: flex; gap: 16px; max-inline-size: 952px; margin: 0 auto; padding: 14px; border: 0; }
.faq__col { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 16px; }
.faq__item {
  border: 1px solid var(--t-line); border-radius: 14px; overflow: hidden;
  background: transparent; transition: background-color 0.45s cubic-bezier(0.6, 0.6, 0, 1);
}
.faq__item[open] { background: var(--t-open); }
.faq__q {
  padding: 23px 15px 18px 23px; gap: 12px;
  font-size: 14px; line-height: 22px; font-weight: 500; letter-spacing: -0.01em; color: var(--t-ink);
}
.faq__q::after {
  inline-size: 24px; block-size: 24px; background: currentColor; opacity: 0.5;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 10 5 5 5-5'/%3E%3C/svg%3E") center / 24px no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 10 5 5 5-5'/%3E%3C/svg%3E") center / 24px no-repeat;
  transition: transform 0.45s cubic-bezier(0.6, 0.6, 0, 1);
}
.faq__item[open] > .faq__q::after { transform: rotate(180deg); }
.faq__q:focus-visible { outline-offset: -2px; border-radius: 14px; }
.faq__a { padding: 0 16px 23px 23px; }
.faq__a p { font-size: 14px; line-height: 22px; color: var(--t-ink-2); max-width: none; }
.faq__item::details-content { transition: block-size 0.45s cubic-bezier(0.6, 0.6, 0, 1), content-visibility 0.45s allow-discrete; }
/* Where the answer's height can't ease (no interpolate-size: Safari, Mac
   and iPhone), the answers swap in one frame, so the box's shading and the
   chevrons easing over 0.45s around them read as a flicker (owner's iPhone,
   2026-10-06). There everything changes together, at once. */
@supports not (interpolate-size: allow-keywords) {
  .faq__item, .faq__q::after, .faq__item::details-content { transition: none; }
}
.faq__more {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 4px;
  margin: 42px 0 0; padding: 16px 32px; font-size: 14px; line-height: 22px; color: var(--t-ink-2);
}
.faq__more a {
  padding: 0 5px; border-radius: 6px; background: var(--t-well); color: var(--t-ink); text-decoration: none;
  transition: background-color 0.45s cubic-bezier(0.6, 0.6, 0, 1);
}
.faq__more a:hover { background: var(--t-well-hover); }
@media (max-width: 40rem) {
  .faq__head { margin-block-end: 16px; }
  .faq__list { flex-direction: column; gap: 0; padding: 0; }
  .faq__col { gap: 0; }
  /* their phone list: one stack, boxes joined, only the outer corners round */
  .faq__item { border-radius: 0; border-block-end-width: 0; }
  .faq__col:first-child .faq__item:first-child { border-radius: 14px 14px 0 0; }
  .faq__col:last-child .faq__item:last-child { border-radius: 0 0 14px 14px; border-block-end-width: 1px; }
  .faq__q { padding: 18px 15px 16px 18px; }
  .faq__a { padding: 0 16px 20px 18px; }
}

/* ============================================ closing panel (2026-09-29)
   Their close: the last section is a contained night panel, not a band.
   Ours holds a whole form, so the form sits on a white card inside it (the
   fields stay as legible as on the page), and only the intro reads on the
   dark. The band keeps the paper and the curtain's rounded foot; the old
   blue glow is dropped, the panel does its job. */
.ask, .ask.band { background: var(--color-paper); }
.ask.band { padding-block: 24px 64px; }
.ask .ask__grid {
  inline-size: calc(100% - 2 * var(--page-gutter)); max-inline-size: 76rem;
  padding: 64px 56px 56px 64px;
  background: #141414; color: rgb(255 255 255 / 0.88);
  border-radius: 28px;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 32px 72px;
}
.ask .ask__grid > div:first-child { padding-block-start: 8px; }
.ask h2 {
  background: linear-gradient(rgb(255 255 255 / 0.9), rgb(255 255 255 / 0.75));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.ask .eyebrow { background: rgb(255 255 255 / 0.08); color: rgb(255 255 255 / 0.64); }
.ask__p { color: #a4a4a4; }
.ask .form { background: #fff; border-radius: 20px; padding: 32px; color: var(--color-ink); }
@media (max-width: 60rem) {
  .ask .ask__grid { grid-template-columns: minmax(0, 1fr); padding: 48px 32px 32px; gap: 32px; }
  .ask .ask__grid > div:first-child { padding-block-start: 0; }
}
@media (max-width: 40rem) {
  .ask.band { padding-block: 16px 40px; }
  .ask .ask__grid { inline-size: calc(100% - 24px); padding: 40px 8px 8px; border-radius: 24px; }   /* 12px off the edges, as every phone card (2026-09-29; was 8px) */
  .ask .ask__grid > div:first-child { padding-inline: 16px; }
  .ask .form { padding: 24px 16px; border-radius: 18px; }
}
/* ======================================= end of closing panel (delete from the "closing panel" header to here to undo) */

/* ============================================ ToDesktop footer (2026-09-29)
   Their light footer, measured at 1280 and 375: a 6% hairline on top, a
   1128px column with 120px above and below, the brand and a pill on one
   row, a 4% rule 56px down, four 14/22 link columns (titles #a4a4a4, links
   ink) 56px down, a rule 90px down, and the meta row 64px under it. Phones:
   one column, 40px steps; the columns fold (see below). The curtain
   reveal is off: a light page lifting off a light footer shows nothing.
   The old dark footer: lab/footer-backup.html. */
:root { --radius-reveal: 0px; }
.tf { border-block-start: 1px solid var(--t-line); background: var(--color-paper); color: var(--t-ink); }
.tf__in { max-inline-size: calc(1128px + 2 * var(--page-gutter)); margin-inline: auto; padding: 120px var(--page-gutter); }
.tf__head { display: flex; align-items: center; justify-content: space-between; gap: 24px; min-block-size: 48px; }
.tf__brand { font-size: var(--text-lg); color: var(--t-ink); text-decoration: none; }
.tf__pill {
  display: inline-flex; align-items: center; gap: 4px; block-size: 32px; padding: 5px 13px 5px 5px;
  border: 1px solid var(--t-line); border-radius: 999px;
  font-size: 14px; line-height: 22px; color: var(--t-ink); text-decoration: none;
  transition: background-color 200ms;
}
.tf__pill:hover { background: var(--t-hover); }
.tf__dot { position: relative; inline-size: 20px; block-size: 20px; flex: none; }
.tf__dot::before, .tf__dot::after { content: ""; position: absolute; inset: 7px; border-radius: 999px; background: #14a362; }
.tf__dot::before { box-shadow: 0 0 0 4px rgb(20 163 98 / 0.12); }
@media (prefers-reduced-motion: no-preference) {
  .tf__dot::after { animation: tf-glow 2.4s ease-out infinite; }
}
@keyframes tf-glow { from { opacity: 0.6; transform: scale(1); } to { opacity: 0; transform: scale(2.6); } }
.tf__rule { block-size: 1px; background: var(--t-line-2); margin-block-start: 56px; }
.tf__rule--end { margin-block-start: 90px; }
.tf__links { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 24px; margin-block-start: 56px; }
.tf__col { display: flex; flex-direction: column; gap: 15px; min-inline-size: 0; }
.tf__h { margin: 0; font-family: var(--font-body); font-size: 14px; line-height: 22px; font-weight: 400; letter-spacing: 0; color: var(--t-ghost); }
.tf__list { display: flex; flex-direction: column; gap: 12px; margin: 0; padding: 0; list-style: none; }
.tf__list li { font-size: 14px; line-height: 22px; color: var(--t-ink); }
.tf__a { color: var(--t-ink); text-decoration: none; transition: color 150ms; }
.tf__a:hover { color: var(--t-ink-2); }
.tf__k { color: var(--t-ghost); margin-inline-end: 4px; }
.tf .foot__todo { font-size: 14px; }
.tf__meta { display: flex; justify-content: space-between; align-items: center; gap: 24px; margin-block-start: 64px; }
.tf__meta p { margin: 0; font-size: 14px; line-height: 22px; }
.tf__copy { color: var(--t-ghost); }
.tf__copy a { color: inherit; text-underline-offset: 3px; }
.tf__copy a:hover { color: var(--t-ink-2); }
/* the line sits under the wordmark (owner, 2026-10-05): the bottom row
   carried copyright, links, two switches and this line, and read crowded;
   now it is the copyright line at the start, the switches at the end */
.tf__id { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }   /* start: the wordmark keeps ltr inside, and stretched it hugged the left in Arabic */
.tf__line { margin: 0; font-size: 14px; line-height: 22px; color: var(--t-ink-2); }
@media (max-width: 60rem) {
  .tf__links { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 40px; }
}
@media (max-width: 40rem) {
  .tf__in { padding: 64px 24px; }
  .tf__head { flex-direction: column; align-items: flex-start; }
  .tf__rule { margin-block-start: 40px; }
  .tf__links { grid-template-columns: minmax(0, 1fr); gap: 28px 24px; margin-block-start: 40px; }
  .tf__rule--end { margin-block-start: 40px; }
  .tf__meta { flex-direction: column; align-items: flex-start; gap: 16px; margin-block-start: 24px; }
}
/* The columns fold on phones (2026-09-29, owner; ClickUp's model, as the
   old dark footer did): theirs doesn't fold, but it is a sitemap for a
   product site, and ours only jumps back up this one page, so unfolded it
   ran 1,360px at 375. Each column is a <details>: above 40rem always open
   and the summary is a plain heading (app.js, footer folds); on phones a
   hairline row with a chevron, Contact starting open. */
.tf__fold { display: block; }
.tf__sum { display: block; list-style: none; margin-block-end: 15px; cursor: default; }
.tf__sum::-webkit-details-marker { display: none; }
@media (max-width: 40rem) {
  /* the rows' own hairlines replace the two dividers, which sat 40px off
     them as doubled lines */
  .tf__rule { display: none; }
  .tf__links { gap: 0; margin-block-start: 32px; }
  .tf .tf__meta { margin-block-start: 32px; }
  .tf__fold { border-block-end: 1px solid var(--t-line); }
  .tf__links { border-block-start: 1px solid var(--t-line); }   /* the rows' top edge, whichever row comes first */
  .tf__fold[data-phone-open] { order: -1; }   /* Contact first: open, then the folded rows (owner, 2026-09-29) */
  .tf__sum {
    display: flex; align-items: center; justify-content: space-between;
    min-block-size: 52px; margin: 0; cursor: pointer;
  }
  .tf__sum .tf__h { font-size: 16px; line-height: 24px; color: var(--t-ink); }
  .tf__sum::after {
    content: ""; inline-size: 8px; block-size: 8px; margin-inline-end: 4px;
    border-inline-end: 1.5px solid var(--t-ghost); border-block-end: 1.5px solid var(--t-ghost);
    rotate: 45deg; translate: 0 -2px; transition: rotate 200ms var(--ease-out), translate 200ms var(--ease-out);
  }
  .tf__fold[open] > .tf__sum::after { rotate: 225deg; translate: 0 2px; }
  .tf__fold .tf__list { padding-block: 4px 20px; }
  .tf__sum:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
}
/* ======================================= end of ToDesktop footer (delete from the "ToDesktop footer" header to here, and restore lab/footer-backup.html, to undo) */

/* The form's chips invite a pick (2026-09-29, owner; stronger the same day:
   the first wave was barely noticeable). A light passes through the chips
   in reading order while nothing is picked (JS needWave): each one in turn
   lifts 4px, fills pale blue with a blue ring, a shine crosses it, and its
   + turns blue and spins. 90ms apart, so it reads as one light travelling
   the rows. A pick gets a short pop. Both off under reduced motion. */
@keyframes need-wave {
  0%, 100% { translate: 0 0; border-color: var(--color-rule); background-color: var(--color-card); box-shadow: none; background-position: 130% 0; }
  35%, 55% { translate: 0 -4px; border-color: var(--color-accent); background-color: color-mix(in oklab, var(--color-accent) 9%, var(--color-card)); box-shadow: 0 10px 20px -10px color-mix(in oklab, var(--color-accent) 70%, transparent); }
  100% { background-position: -30% 0; }
}
@keyframes need-wave-plus { 0%, 100% { opacity: 0.5; rotate: 0deg; } 40%, 60% { opacity: 1; rotate: 180deg; } }
@keyframes need-pop { 0% { scale: 1; } 40% { scale: 0.94; } 100% { scale: 1; } }
@media (prefers-reduced-motion: no-preference) {
  .need.is-wave .need__opt span {
    background-image: linear-gradient(105deg, transparent 35%, rgb(255 255 255 / 0.9) 50%, transparent 65%);
    background-size: 250% 100%; background-repeat: no-repeat;
    animation: need-wave 1000ms cubic-bezier(0.45, 0, 0.25, 1) both; animation-delay: calc(var(--i, 0) * 90ms);
  }
  .need.is-wave .need__opt span::before { color: var(--color-accent); animation: need-wave-plus 1000ms cubic-bezier(0.45, 0, 0.25, 1) both; animation-delay: calc(var(--i, 0) * 90ms); }
  .need__opt input:checked + span { animation: need-pop 260ms cubic-bezier(0.3, 0.7, 0.4, 1); }
}

/* The nav button's light (2026-09-29, owner; JS ctaLight). A 2px ring 4px
   outside "Let's talk", drawn by a masked conic gradient whose angle turns:
   while Pricing is mid-screen the light keeps circling (data-glow), and
   stops past it; at the form it circles again on a lit ring (data-live). */
/* Phones (owner, 2026-10-01): no nav button there, so the same light rings
   Pricing's own "Talk to us" while Pricing holds the middle of the screen
   (JS sets data-glow on both; CSS shows it only where it belongs).
   The light is a span in each button (.cta-ring > i), turned by transform
   (2026-10-04, owner's phone recording): it was a conic gradient whose
   angle was animated (@property), which the browser repaints on the main
   thread every frame, forever, hidden or not; on iPhones that took the
   frames the page's scroll and the case stills needed, and both stuttered
   past Pricing. A turning transform runs on the compositor. The ring's
   shape is the same mask on the span; the gradient inside it turns. */
.nav__cta, .btn[data-turns-blue] { position: relative; }
.nav__cta::before, .cta-ring {
  content: ""; position: absolute; inset: -4px; border-radius: inherit; padding: 2px; pointer-events: none;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: 0; transition: opacity 600ms cubic-bezier(0.4, 0, 0.2, 1);
}
.nav__cta::before { background: color-mix(in oklab, var(--color-accent) 48%, transparent); }
.cta-ring { display: block; overflow: hidden; }
.cta-ring i {
  position: absolute; left: 50%; top: 50%; inline-size: 150%; aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: conic-gradient(transparent 0 50%, color-mix(in oklab, var(--color-accent) 70%, transparent) 70%, var(--color-accent) 82%, #6fa4ff 91%, #fff 95%, transparent 99%);
}
@keyframes cta-spin { to { transform: translate(-50%, -50%) rotate(360deg); } }
.nav__cta[data-glow] .cta-ring, .nav__cta[data-live] .cta-ring, .nav__cta[data-live]::before { opacity: 1; }
@media (max-width: 40rem) {
  .btn[data-turns-blue][data-glow] .cta-ring { opacity: 1; }
  /* and, as "Let's talk" does, the button wears the grey pill while its light
     plays, blue already passed or not, so the light is the one blue thing */
  .btn[data-turns-blue][data-glow]:not(:hover) { --btn-bg: var(--color-pill); --btn-fg: var(--color-ink); box-shadow: none; }
}
@media (prefers-reduced-motion: no-preference) {
  /* it turns only while it shows; paused, it holds where it is as it fades
     out, so it never snaps back to the start mid-fade (the flicker past
     Pricing the owner saw when the spin was removed outright) */
  .cta-ring i { animation: cta-spin 3.2s linear infinite; animation-play-state: paused; }
  :is([data-glow], [data-live]) > .cta-ring i { animation-play-state: running; }
}

/* The hero's tease (2026-09-29, owner: show what's next without scrolling).
   Type and sizes are fixed, so how much panel peeks depended only on screen
   height: 25px at 1280×800, none at 1366×768. On laptop-short screens the
   whitespace between the hero's blocks gives back up to 60px, in proportion
   (--tease grows as the screen shortens, 0 from 839px tall up), so the
   panel's top shows about 64px at 800 and 52px at 768. Nothing is trimmed on
   taller screens or phones, and no text or button changes size. */
@media (min-width: 60rem) {
  :root { --tease: clamp(0px, 839px - 100svh, 60px); }
  .hero { padding-block-start: calc(var(--nav-h) + 14px - var(--tease) * 0.1); }
  .hero__stage { margin-block-start: calc(36px - var(--tease) * 0.35); }
  .steps { margin-block-end: calc(20px - var(--tease) * 0.15); }
  .steps__track { margin-block-end: calc(32px - var(--tease) * 0.3); }
  .steps__icon { margin-block-end: calc(16px - var(--tease) * 0.05); }
  .steps__tab { padding-block-start: calc(16px - var(--tease) * 0.05); }
}
/* Shorter still (a laptop browser around 720px tall, the owner's own): the
   spacing alone can't bring the panel up, the hero's content is taller than
   the screen. There the steps keep their icons and titles and drop the
   descriptions, as tablets already do (and the panel shows each step), so
   ~40px of the panel still peeks. */
@media (min-width: 60rem) and (max-height: 760px) {
  .steps__d { display: none; }
}

/* The nav arrives, as ToDesktop's (2026-09-29, owner; JS navTone). At the
   top the bar is in flow and not sticky, so it scrolls away with the hero.
   Past the headline its row becomes the fixed white pill (the look is the
   data-tone="light" block above) and drops in from above: 320ms, fading in
   and growing from 92%, with a small settle, as measured on theirs. The bar
   keeps its 82px in the flow the whole time, so nothing shifts. */
.nav { position: relative; }
.nav[data-tone="light"] .nav__inner {
  position: fixed; inset-block-start: 0; inset-inline: 0; margin-inline: auto; z-index: var(--z-sticky);
  transition: background-color 300ms, box-shadow 300ms;
}
@keyframes nav-arrive {
  from { translate: 0 -72px; scale: 0.92; opacity: 0; }
  70% { translate: 0 3px; scale: 1.005; opacity: 1; }
  to { translate: 0 0; scale: 1; opacity: 1; }
}
@media (prefers-reduced-motion: no-preference) {
  .nav[data-tone="light"] .nav__inner { animation: nav-arrive 320ms cubic-bezier(0.2, 0.7, 0.3, 1) both; }
}

/* The nav at the top, as ToDesktop's (2026-09-29, owner: all three). Over
   the sky: plain links (no pill round them), their raised-tab frame line
   round the links (.nav__frame, 1:1, faded at both ends; it replaced the
   notch in the sky's lines), and "Let's talk" as their dark "Log in" pill,
   shown from the start (it used to wait for the hero's buttons to leave, to
   keep one call to action; the grey pill is quiet enough beside the blue
   one). In the floating pill it's the blue button again. */
.nav__frame { display: none; }
@media (min-width: 60rem) {
  .nav__frame {
    display: block; position: absolute; inset: 0; overflow: hidden; pointer-events: none;
    -webkit-mask-image: linear-gradient(90deg, transparent 10%, #000 30%, #000 70%, transparent 90%);
            mask-image: linear-gradient(90deg, transparent 10%, #000 30%, #000 70%, transparent 90%);
  }
  .nav__frame svg { position: absolute; inset-block-start: 0; left: 50%; translate: -50% 0; fill: none; stroke: #fff; stroke-opacity: 0.09; stroke-width: 1; }
  .nav[data-tone="light"] .nav__frame { display: none; }
}
.nav[data-tone="dark"] .nav__links { background: transparent; box-shadow: none; border-color: transparent; }
.nav[data-tone="dark"] .nav__link { color: rgb(255 255 255 / 0.7); }
/* their hover over the sky: a dark glass pill behind the link, lit along
   its top edge, with a soft drop (owner's screenshot of theirs) */
.nav[data-tone="dark"] .nav__link { transition: color 200ms var(--ease-out), background-color 200ms var(--ease-out), box-shadow 200ms var(--ease-out); }
.nav[data-tone="dark"] .nav__link:hover {
  color: #fff;
  background-color: rgb(255 255 255 / 0.08);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.12), inset 0 0 0 1px rgb(255 255 255 / 0.05), 0 6px 16px -6px rgb(0 0 0 / 0.5);
}
.nav[data-tone="dark"] .nav__cta,
.nav[data-tone="dark"][data-cta="held"] .nav__cta {
  opacity: 1; visibility: visible; transform: none;
  /* the same glass as the language switch beside it (.lsw, dark nav), so
     the two read as a pair (owner, 2026-10-05; it was a flat 10% fill) */
  --btn-bg: transparent;
  background-image: linear-gradient(180deg, rgb(255 255 255 / 0.16), rgb(255 255 255 / 0.06));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.28), inset 0 0 0 1px rgb(255 255 255 / 0.12), 0 6px 18px -6px rgb(0 0 0 / 0.45);
}
/* hover brightens by a white wash under the gradient: background-color
   eases (300ms, the nav CTA's transition), a swapped gradient would snap */
.nav[data-tone="dark"] .nav__cta:hover { --btn-bg: rgb(255 255 255 / 0.06); }

/* ================================================= dark theme: components
   (2026-09-29). Most of the page turns by its tokens (tokens.css, the dark
   theme block); these are the few pieces drawn in fixed colours that need
   their own night version. Everything here is scoped to [data-theme="dark"],
   so the light theme is untouched. */
[data-theme="dark"] .seg__pill {
  background: rgb(255 255 255 / 0.1);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.08), 0 6px 12px -6px rgb(0 0 0 / 0.5);
}
/* Custom builds: with every card dark, their ink card would read as one
   more grey, so it takes their CTA panel's night-to-blue instead */
[data-theme="dark"] .pcard--dark {
  background: linear-gradient(170deg, #1b1250 0%, #0b1170 55%, #0a2aa8 100%);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.08);
}
[data-theme="dark"] .pcard--dark .pcard__list span { color: #b9bdd8; }
[data-theme="dark"] .pcard--dark .pcard__d, [data-theme="dark"] .pcard--dark .pcard__unit,
[data-theme="dark"] .pcard--dark .pcard__note, [data-theme="dark"] .pcard--dark .pcard__k { color: #aeb3d6; }
[data-theme="dark"] .pcard--dark .pcard__list svg { stroke: #8a90c4; }
/* Send us your website: the ink panel would sink into the night, so it
   becomes their CTA panel's night-to-blue; the form card goes dark glass
   (a white card would glare), its fields already dark by the tokens */
[data-theme="dark"] .ask .ask__grid {
  background: linear-gradient(160deg, #13023a 0%, #070b6b 52%, #0a2aa8 115%);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.08);
}
[data-theme="dark"] .ask .form {
  background: rgb(14 10 25 / 0.72); color: var(--color-ink);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.08), 0 24px 48px -24px rgb(0 0 0 / 0.6);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
}
/* the hero in dark (owner, option A): the bright blue band sinks into a
   midnight sky, deep navy with one dim blue glow where the panel sits, then
   back into the night page; switching at the top now visibly turns the sky */
[data-theme="dark"] .hero__sky {
  background:
    radial-gradient(ellipse 60% 26% at 50% 58%, rgb(40 70 200 / 0.28), transparent 70%),
    linear-gradient(180deg,
      #0a0715 0%, #0c0819 16%, #0f0a26 30%, #0f0d38 42%, #10124a 54%,
      #0f1352 62%, #0d0f3f 72%, #0c0b2b 84%, var(--color-paper) 100%);
}

/* The theme toggle (2026-09-29, owner's plan). A 36px round button left of
   "Let's talk" in the hero's nav, glass on the sky; not in the floating
   pill (owner).
   The icon shows where it takes you: a moon in light, a sun in dark. */
.nav__inner > .nav__end { grid-column: 3; justify-self: end; display: flex; align-items: center; gap: 8px; }
.theme {
  display: inline-flex; align-items: center; block-size: 36px; min-inline-size: 36px; flex: none;
  padding: 0 9px; border: 0; border-radius: 999px; cursor: pointer;
  font: 500 14px/20px var(--font-body); white-space: nowrap;
  background: var(--t-well); color: var(--t-ink);
  transition: background-color 200ms var(--ease-out), color 200ms var(--ease-out);
}
.theme:hover { background: var(--t-well-hover); }
.theme:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
/* Apple's Appearance mark (owner): a ring, its left half filled; in dark
   the filled half turns to the right, the way the page has turned */
.theme__icon { inline-size: 18px; block-size: 18px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; }
.theme__half { fill: currentColor; stroke: none; transform-origin: 12px 12px; transition: rotate 450ms cubic-bezier(0.6, 0.05, 0.3, 1); }
[data-theme="dark"] .theme__half { rotate: 180deg; }
/* the words it expands to on the hero (owner): where the button takes you */
.theme__label { display: block; max-inline-size: 0; overflow: hidden; opacity: 0; margin-inline-start: 0;
  transition: max-inline-size 350ms cubic-bezier(0.6, 0.6, 0, 1), opacity 250ms var(--ease-out), margin 350ms cubic-bezier(0.6, 0.6, 0, 1); }
.theme__to-light, [data-theme="dark"] .theme__to-dark { display: none; }
[data-theme="dark"] .theme__to-light { display: inline; }
.nav[data-tone="dark"] .theme { background: rgb(255 255 255 / 0.1); color: #fff; box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.06); }
.nav[data-tone="dark"] .theme:hover { background: rgb(255 255 255 / 0.16); }
/* on the hero only (the floating pill stays an icon): hovering or tabbing
   to it opens the pill out to the left with its words */
@media (hover: hover) {
  .nav[data-tone="dark"] .theme:hover .theme__label { max-inline-size: 90px; opacity: 1; margin-inline-start: 6px; }
}
.nav[data-tone="dark"] .theme:focus-visible .theme__label { max-inline-size: 90px; opacity: 1; margin-inline-start: 6px; }
@media (max-width: 40rem) { .theme { block-size: 34px; min-inline-size: 34px; padding-inline: 8px; } }
/* only on the hero: the floating pill carries no toggle (owner) */
.nav[data-tone="light"] .theme { display: none; }

/* The switch, as macOS changes appearance (owner): the whole page
   cross-dissolves from one theme to the other, evenly, in under half a
   second (a View Transition; browsers without it, and reduced motion,
   switch at once). It replaced a circle spreading from the button. */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 450ms; animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
/* The language switch dissolves the same way (owner's brother: it
   popped): a cross-document View Transition between index.html and
   ar.html, same 450ms. Whole page only; the layout mirrors, so nothing
   is pinned or slid (the wordmark changes sides). Browsers without it,
   and reduced motion, switch at once. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
/* the floating pill on the night: a faint ring so it lifts off the page */
[data-theme="dark"] .nav[data-tone="light"] .nav__inner {
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.07), rgb(0 0 0 / 0.3) 0 4px 16px, rgb(0 0 0 / 0.3) 0 16px 56px;
}

/* the footer's switch (owner, after a reference): a small outlined pill of
   two icons, light and dark, with a white disc sliding under the chosen one */
.tf__left { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.tseg {
  position: relative; display: inline-flex; padding: 2px; gap: 2px; border-radius: 999px;
  box-shadow: inset 0 0 0 1px var(--t-line); background: var(--t-hover);
}
.tseg__dot {
  position: absolute; inset-block: 2px; inset-inline-start: 2px; inline-size: 28px; border-radius: 999px;
  background: #fff; box-shadow: 0 1px 2px rgb(0 0 0 / 0.08), 0 2px 6px rgb(0 0 0 / 0.06);
  transition: translate 350ms cubic-bezier(0.6, 0.05, 0.3, 1), background-color 300ms;
}
[data-theme="dark"] .tseg__dot { translate: 30px 0; background: rgb(255 255 255 / 0.14); box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.1); }
.tseg__opt {
  position: relative; display: grid; place-items: center; inline-size: 28px; block-size: 28px;
  padding: 0; border: 0; border-radius: 999px; background: none; cursor: pointer; color: var(--t-ghost);
  transition: color 200ms var(--ease-out);
}
.tseg__opt:hover, .tseg__opt[aria-checked="true"] { color: var(--t-ink); }
.tseg__opt:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 1px; }
.tseg__opt svg { inline-size: 16px; block-size: 16px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
@media (prefers-reduced-motion: reduce) { .tseg__dot { transition: none; } }

/* WhatsApp in our blue (2026-09-29, owner, after ToDesktop's chat button):
   the button blue with a white glyph and their soft shadow, so it reads as
   one more way to reach us; the 2px white ring stays (white in both themes)
   so it holds its edge over the hero's blue sky, where plain blue would
   vanish. Hover goes a step brighter, as the buttons do. */
.wa {
  background: #0335fb; background: color(display-p3 0.0118 0.2067 0.9861); color: #fff;
  border-color: #fff;
  box-shadow: 0 6px 20px rgb(3 30 160 / 0.32), 0 2px 6px rgb(0 0 0 / 0.12);
}
.wa:hover { background: color(display-p3 0.1 0.3 1); box-shadow: 0 10px 26px rgb(3 30 160 / 0.38), 0 2px 6px rgb(0 0 0 / 0.12); }

/* the hero's switch (owner, 2026-09-29): the footer's pill in glass for the
   sky, 36px tall to sit level with "Let's talk", a white disc under the
   chosen icon (the hero is night in both themes, so it looks the same in
   both). Only on the hero: the floating pill carries none. It replaced a
   round button that opened out to a label on hover. */
.tseg--nav { box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.08); background: rgb(255 255 255 / 0.08); }
.tseg--nav .tseg__opt { inline-size: 32px; block-size: 32px; color: rgb(255 255 255 / 0.6); }
.tseg--nav .tseg__opt:hover { color: #fff; }
.tseg--nav .tseg__opt[aria-checked="true"] { color: #141414; }
.tseg--nav .tseg__dot, [data-theme="dark"] .tseg--nav .tseg__dot {
  inline-size: 32px; background: #fff; box-shadow: 0 1px 2px rgb(0 0 0 / 0.2), 0 4px 10px rgb(0 0 0 / 0.2);
}
[data-theme="dark"] .tseg--nav .tseg__dot { translate: 34px 0; }
.tseg--nav .tseg__opt:focus-visible { outline-color: #fff; }
.nav[data-tone="light"] .tseg--nav { display: none; }
/* the deck's white tiles draw in the page ink, which turns near-white in
   dark and left their icons invisible; the hero is night in both themes,
   so their ink stays fixed */
[data-theme="dark"] .deck__tile.t-white { --stroke: #141414; --fg: #141414; }

/* a tiny label on hover (owner): each icon names itself in a small pill,
   under the hero's switch (white on the sky) and above the footer's (ink on
   the page, turning with the theme); fades and rises in after a beat, as a
   tooltip does; also on keyboard focus; never on touch */
.tseg__opt[data-tip]::after {
  content: attr(data-tip); position: absolute; inset-inline-start: 50%; z-index: 5;
  padding: 3px 8px; border-radius: 6px; white-space: nowrap; pointer-events: none;
  font: 500 12px/16px var(--font-body); letter-spacing: 0;
  background: var(--t-ink); color: var(--color-paper);
  box-shadow: 0 4px 12px rgb(0 0 0 / 0.16);
  opacity: 0; translate: -50% 4px;
  transition: opacity 160ms var(--ease-out), translate 200ms var(--ease-out);
}
.tseg--nav .tseg__opt[data-tip]::after { inset-block-start: calc(100% + 10px); background: #fff; color: #141414; translate: -50% -4px; }
.tf .tseg__opt[data-tip]::after { inset-block-end: calc(100% + 8px); }
@media (hover: hover) {
  .tseg__opt[data-tip]:hover::after { opacity: 1; translate: -50% 0; transition-delay: 250ms; }
}
.tseg__opt[data-tip]:focus-visible::after { opacity: 1; translate: -50% 0; }

/* the client's address stays blank while the panel only peeks under the
   first screen (owner): it writes itself in once the panel is properly in
   view (.is-seen, set by heroSteps when it starts playing) or a step is
   clicked. Without JS, or for crawlers, it simply shows. */
.shot__url { display: flex; align-items: center; justify-content: center; box-sizing: border-box; block-size: 24px; line-height: 20px; transition: color 400ms var(--ease-out); }
/* In its place, the bar looks like a page that is loading (owner: the empty
   pill looked dry): a browser tab's spinner and "loading a real rebuild"
   with a light running through the words, so the eye expects something to
   arrive below, without saying "scroll". A spinner, not an hourglass: an
   hourglass reads as "slow". The address text is taken out of the flow
   meanwhile (font-size 0), so the pill fits the loading line instead of
   the hidden address (it cut the words off on phones). */
.js .shot:not(.is-seen) .shot__url { font-size: 0; color: transparent; }
.shot__url::before, .shot__url::after { display: none; }
.js .shot:not(.is-seen) .shot__url::before {
  content: ""; display: inline-block; flex: none; margin-inline-end: 7px;
  inline-size: 9px; block-size: 9px; border-radius: 50%;
  border: 1.5px solid rgb(255 255 255 / 0.22); border-block-start-color: rgb(255 255 255 / 0.85);
}
.js .shot:not(.is-seen) .shot__url::after {
  content: "loading a real rebuild"; display: inline; font-size: 11px; line-height: 20px; white-space: nowrap;
  background: linear-gradient(90deg, rgb(255 255 255 / 0.4) 0%, rgb(255 255 255 / 0.4) 40%, #fff 50%, rgb(255 255 255 / 0.4) 60%, rgb(255 255 255 / 0.4) 100%);
  background-size: 250% 100%; -webkit-background-clip: text; background-clip: text; color: transparent;
}
@media (max-width: 40rem) { .js .shot:not(.is-seen) .shot__url::after { font-size: 10px; } }
@media (prefers-reduced-motion: no-preference) {
  .js .shot:not(.is-seen) .shot__url::before { animation: shot-spin 0.9s linear infinite; }
  .js .shot:not(.is-seen) .shot__url::after { animation: shot-loading 2.2s linear infinite; }
}
@keyframes shot-spin { to { rotate: 360deg; } }
@keyframes shot-loading { from { background-position: 100% 0; } to { background-position: -150% 0; } }
/* Built from scratch in dark (owner: the colouring felt off): EuroDecor's
   own near-black site sat edge to edge on our violet night with nothing
   between them, so the three panels smeared into the page. A faint white
   ring and a deep shadow give each its edge, so the neutral black reads as
   their site, framed, not as a patch of the wrong black. */
[data-theme="dark"] .triptych__side,
[data-theme="dark"] .build__frame {
  box-shadow: 0 0 0 1px rgb(255 255 255 / 0.1), 0 30px 60px -30px rgb(0 0 0 / 0.9);
}

/* Pricing cards line up row by row (owner): their notes differ in length,
   so the buttons, rules and "includes" labels sat at different heights.
   Side by side, both cards share the grid's rows (subgrid): name, price,
   note, button, rule, label, list; each row takes the taller card's
   height, and the shorter note simply has air under it. Stacked on phones,
   nothing needs matching. */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 48.0625rem) {
    .pgrid { row-gap: 0; }
    .pcard { display: grid; grid-row: span 7; grid-template-rows: subgrid; }
    .pcard__body { display: grid; grid-row: span 6; grid-template-rows: subgrid; }
    .pcard__body > * { align-self: start; }
  }
}
/* the price reads "From 5,000 SAR" (owner, 2026-09-29; was "5,000 SAR ·
   starting"): the qualifier where the eye starts, in the unit's small grey,
   on the same baseline, the figure still the one big thing */
.pcard__from { margin-inline-end: -1px; }

/* ================================================= Phone flow (2026-09-29)
   ToDesktop's mobile page, cloned for phones (owner: "the exact mobile flow
   ... in every way"). Measured on theirs at 375×812. Phones only: nothing
   here reaches above 40rem. Undo: delete this block, from its header down to
   "end of phone flow" (the carousel's `phone` checks in app.js do nothing
   without it).
   Section order is unchanged (owner). */
@media (max-width: 40rem) {
  /* ---- rhythm: every section 56px top and bottom, no rules between them
     (theirs has none on phones); the pill, then the heading 12px under it,
     the sub 8px under that */
  .band, .band--tight, .band--tall { padding-block: 56px; }
  #case.band { padding-block-start: 56px; }
  /* Redesigned keeps both frames stacked on phones (owner, 2026-09-29: a
     Before / After switch was tried and reverted: the contrast must show
     without a tap) */
  .band + .band { border-block-start: 0; }
  .head-rule { display: none; }
  .head, .more__head, .words__lede { gap: 0; }
  .eyebrow { margin-block-end: 12px; }
  .head__sub, .more__sub { margin-block-start: 8px; font-size: 16px; line-height: 26px; }
  .words__sub { margin-block-start: 8px; }

  /* ---- nav: their silhouette, the logo left and one round control right.
     Their menu leads to other pages; ours would only jump within this one,
     so the one control is "Let's talk" as their dark glass pill. The bar
     scrolls away with the hero and doesn't come back (no floating pill on
     their phones); the WhatsApp button stays fixed, as their chat bubble.
     The theme lives in the footer on phones, and in the hero's ⋮ menu. */
  .tseg--nav { display: none; }
  .nav[data-tone="light"] .nav__inner {
    position: static; animation: none; background: transparent; box-shadow: none;
    max-inline-size: none; block-size: auto; margin-block-start: 0; padding: 0;
  }
  .nav .nav__cta,
  .nav[data-tone] .nav__cta {
    --btn-bg: rgb(255 255 255 / 0.1); background: rgb(255 255 255 / 0.1); color: #fff;
    box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.06);
    min-height: 36px; padding: 7px 16px; opacity: 1; visibility: visible; transform: none;
  }
  .nav__cta::before, .nav__cta .cta-ring { display: none; }

  /* ---- hero: their buttons sit at their own width, centred, 46px, 16px */
  .hero__actions { justify-content: center; }
  .hbtn { flex: none; font-size: 16px; line-height: 24px; block-size: 46px; padding: 11px 16px 11px 14px; }
  .hbtn--primary { padding-inline-end: 10px; }

  /* ---- Built from scratch: their feature card, 12px off the screen edges,
     24px corners, 4% grey, the words centred over the live site */
  .build {
    margin-inline: calc(12px - var(--page-gutter)); padding: 40px 16px 16px;
    background: var(--t-well, rgb(55 55 55 / 0.04)); border-radius: 24px; text-align: center;
  }
  .build__ask { display: flex; flex-direction: column; align-items: center; text-align: center; }
  .build__arrow, .build__figure .dip__label { margin-inline: auto; justify-content: center; }
  .build__actions { padding-block-end: 24px; }
  /* the Arabic and narrow tags sat on the pictures, over the very parts
     that prove the point (the Arabic paragraph, the narrow buttons); on
     phones they are captions under each picture (owner, 2026-09-29): the
     panel holds the picture and its caption, the picture keeps the corners */
  .triptych__side { aspect-ratio: auto; overflow: visible; border-radius: 0; background: none; display: flex; flex-direction: column; gap: 8px; }
  .triptych__side img { aspect-ratio: 3 / 4; block-size: auto; border-radius: var(--radius-lg); background: var(--color-paper-2); }
  .triptych__tag {
    position: static; align-self: center; padding: 0; background: none; border-radius: 0;
    font-size: 11px; line-height: 16px; color: var(--t-ink-2);
  }
  [data-theme="dark"] .triptych__side { box-shadow: none; }
  [data-theme="dark"] .triptych__side img { box-shadow: 0 0 0 1px rgb(255 255 255 / 0.1), 0 30px 60px -30px rgb(0 0 0 / 0.9); }

  /* ---- Services keeps its Squarespace carousel on phones (tabs, text on
     the drawing, dots, autoplay), with one change: the card sits 12px off
     the screen edges with 24px corners, like every other card here, instead
     of full bleed. The 24px gap keeps the neighbours out of view. (Stacked
     cards, then a swipe row of ToDesktop's cards, were tried and dropped
     the same day, owner: the tabs name the range at a glance and the
     drawings keep their own composition.) */
  .more { --card-w: calc(100vw - 24px); }
  .more__track { gap: 24px; }
  .mcard { border-radius: 24px; }
  /* Bookings and Invoicing flickered on phones, mostly on first load (owner,
     2026-09-29): their drawings are the filter-heavy ones (blurs on clipped
     shapes, animated blurred steam, a soft-light noise blend, a drop-shadow
     on the clipped lamp shade) inside a card that is both moving and clipped
     to rounded corners, which WebKit re-rasterises unevenly. Each card gets
     its own stable layer, and those filters go: at phone size they are 1-3px
     and the gradients underneath are already soft; the grain goes too. */
  /* (each card's own layer now applies at every width, see .mcard) */
  .desk__lamp::after { filter: none; }   /* (the spa's blurs and grain are gone at every width since 2026-10-08) */
  .scene--night::after { content: none; }   /* the grain: invisible at this size */
  /* Then (owner's video, 2026-09-30): Online store and Bookings still went
     blank for a moment as they arrived, the room showing without its text
     and mockups. They are the only cards with animated steam, paused off
     screen and started when the card becomes active; starting it made
     WebKit rebuild the card's layers under the mockups. On phones the steam
     holds still, as it does for reduced motion. */
  /* (the steam holds still at every width since 2026-10-08) */

  /* ---- the quotes and Who's behind: the same 12px edges and 24px gaps */
  .words__row { margin-inline: calc(12px - var(--page-gutter)); gap: 24px; }
  .about { text-align: center; }
  .about__title { margin-inline: auto; }
  /* the intro stays centred (owner, tested on a real phone, 2026-09-29; a
     left-aligned version on the rows' edge was tried the same day) */
  .about__p { margin-inline: auto; font-size: 16px; line-height: 26px; }
  .about > div:first-child .eyebrow { margin-inline: auto; }
  .about__people {
    margin-inline: calc(12px - var(--page-gutter)); padding: 0; gap: 0; border: 0; text-align: start;
    border-block-start: 1px solid var(--t-line);   /* closes the intro and opens the list (owner) */
  }
  .person { padding: 32px 18px 32px 32px; border-block-end: 1px solid var(--t-line, rgb(22 22 22 / 0.06)); align-items: center; }
  .person:last-child { border-block-end: 0; }
}
/* ================================================= end of phone flow */

/* The hero emblem is the symbols alone (owner, 2026-09-30: keep the art,
   drop the tile around it). No glass, rim, shadow, glow or veil; every
   symbol is white on the sky with its one detail in the light blue (AI
   agents keeps its gradient spark). With no tiles there is no stack to
   peek, so the two waiting slots are hidden: the front symbol drops away
   and the next arrives from above, as before. At the end of the file so
   it also outranks the dark theme's white-tile ink. Undo = delete this block. */
.hero .deck .deck__tile {
  background: none; box-shadow: none;
  --stroke: #fff; --fg: #fff; --acc: var(--color-accent-light); --cut: var(--deck-sky, oklch(30% 0.06 280));
}
.hero .deck .deck__tile.t-ai { --acc: url(#deck-ai); }
.hero .deck .deck__tile::before, .hero .deck .deck__tile::after { display: none; }
.hero .deck .deck__tile svg { inline-size: 88%; block-size: 88%; filter: drop-shadow(0 6px 14px rgb(8 1 20 / 0.28)); }
.hero .deck .deck__tile[data-slot="1"], .hero .deck .deck__tile[data-slot="2"] { opacity: 0; }
/* no tile hides the handover any more, so the two symbols must not cross:
   the leaving one clears quickly, and the next waits for it */
.hero .deck .deck__tile[data-slot="out"] { transition: transform 260ms var(--ease-out), opacity 200ms var(--ease-out); }
.hero .deck .deck__tile[data-slot="0"] { transition-delay: 220ms; }

/* Redesigned's scrubber, upright in the right margin (owner, 2026-09-30),
   where the case arrows stood: it scrolls both pages up and down, so it now
   moves the way they do, top of the pages at the top. It spans the frames
   exactly (app.js sets --scrub-top and --scrub-h). Only where the margin can
   hold it, 70rem up, as the arrows were; narrower screens keep the
   horizontal one under the dock. Undo = delete this block. */
@media (min-width: 70rem) {
  .dip__panel { position: relative; }
  .dip__scrub {
    position: absolute; left: calc(100% + 6px); top: var(--scrub-top, 0);
    writing-mode: vertical-lr; direction: ltr;
    inline-size: var(--scrub-h, 100%); block-size: 44px;
    cursor: ns-resize;
  }
}
/* Chevrons hugging the knob (owner, 2026-09-30; they replaced a drawn
   mouse pointer that read like a stray cursor): a fine one just above the
   knob and one just below, in the blue, centred on it and riding it (app.js
   sets --scrub-p, 0 at the top to 1 at the bottom; the knob's centre travels
   from 9px to 9px short of each end). Every couple of seconds they nudge
   outward, a quiet "drag up or down". Mouse screens only, where the bar is
   upright; gone the moment the real mouse is on the bar or it has focus. */
.dip__ghost { display: none; }
@media (min-width: 70rem) and (hover: hover) and (pointer: fine) {
  .dip__ghost {
    display: block; position: absolute; z-index: 2; pointer-events: none;
    left: calc(100% + 6px + 22px);
    top: calc(var(--scrub-top, 0px) + 9px + var(--scrub-p, 0) * (var(--scrub-h, 0px) - 18px));
    translate: -50% -50%;
    inline-size: 16px; block-size: 44px; overflow: visible;
    fill: none; stroke: var(--color-accent); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
    transition: opacity 200ms var(--ease-out);
  }
  .dip__ghost path { transform-box: fill-box; }
  .dip__scrub:hover ~ .dip__ghost, .dip__scrub:focus-visible ~ .dip__ghost { opacity: 0; }
  .dip[data-sync="false"] .dip__ghost { display: none; }
}
@media (min-width: 70rem) and (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .dip__ghost-up { animation: ghost-up 2.4s ease-in-out infinite; }
  .dip__ghost-down { animation: ghost-down 2.4s ease-in-out infinite; }
}
/* "Drag to explore" (app.js scrubHint adds .is-on once per visit). Since
   2026-10-05 (owner) it is the old "Scroll inside" annotation, not a pill:
   a short blue dash and the words in small mono caps, written down the
   scrubber's track itself, just under the knob's resting place, on the
   page's paper (the track breaks around it). The frosted pill sat on the
   client's page, over their nav and buttons; this stays in our margin, on
   the very thing it is about. */
.dip__hintpill { display: none; }
@media (min-width: 70rem) and (hover: hover) and (pointer: fine) {
  .dip__hintpill {
    display: flex; align-items: center; gap: 8px;
    position: absolute; z-index: 3; pointer-events: none; white-space: nowrap;
    left: calc(100% + 6px + 22px);
    /* its foot 40px above the track's foot (2026-10-06, owner's brother): it
       sat just under the knob, so the run reached it within ~4s; down here
       it stays ~10s before the knob passes, and is back when the run ends.
       transform (not translate, which the entrance and RTL rules use) lifts
       it by its own height. */
    top: calc(var(--scrub-top, 0px) + var(--scrub-h, 0px) - 40px); transform: translateY(-100%);
    translate: -50% -6px; opacity: 0;
    writing-mode: vertical-rl; text-orientation: upright;   /* letters stacked upright, D R A G … (owner) */
    padding-block: 8px; background: var(--color-paper);
    font: 500 11px/1 var(--font-mono); letter-spacing: 0; text-transform: uppercase; color: var(--color-accent);   /* blue, with its dash (owner, 2026-10-05: grey read too faint) */
    transition: opacity 400ms var(--ease-out), translate 400ms var(--ease-out);
  }
  .dip__hintpill::before { content: ""; flex: none; inline-size: 12px; block-size: 2px; background: var(--color-accent); }
  .dip__hintpill.is-on { opacity: 1; translate: -50% 0; }
  /* stays until touched; steps aside while the knob's run crosses it */
  .dip__hintpill.is-on.is-aside { opacity: 0; }
  /* and comes back centred on the track (app.js, while it is faded out) */
  .dip__hintpill.is-back { top: calc(var(--scrub-top, 0px) + var(--scrub-h, 0px) / 2); transform: translateY(-50%); }
  /* EuroDecor's track is 502px to Redesigned's 355, so "40px above the foot"
     left ~210px of empty track between the knob and the letters: centred
     from the start there (owner, 2026-10-06), up ~9s before the run reaches
     it (Redesigned ~12s), and the same spot when it comes back */
  #build .dip__hintpill { top: calc(var(--scrub-top, 0px) + var(--scrub-h, 0px) / 2); transform: translateY(-50%); }
}
/* the grab hand over the bar, a closed hand while dragging: the cursor people
   read as "you can drag this" (it was a plain up-down resize arrow) */
.dip__scrub { cursor: grab; }
.dip__scrub:active { cursor: grabbing; }
@keyframes ghost-up { 0%, 55%, 100% { translate: 0 0; } 25% { translate: 0 -3px; } }
@keyframes ghost-down { 0%, 55%, 100% { translate: 0 0; } 25% { translate: 0 3px; } }
/* "Hover or drag to scroll both." goes where the upright scrubber and its
   drawn pointer say it already (owner, 2026-09-30); smaller screens, with
   the plain horizontal bar, keep it, worded per device by app.js */
@media (min-width: 70rem) and (hover: hover) and (pointer: fine) {
  .dip__hint-a { display: none; }
}

/* Section chips in the headline icon's blue (owner, 2026-09-30): white type on that tile's own gradient and top
   highlight (.hero__icon), so the chips and the hero's one blue icon are
   the same object. A first pass, blue type on a 10% tint, still read grey.
   Same on the dark closing panel and in both themes, and on every section
   chip (Work joined the same day: the lone grey one read as odd). Undo =
   delete this block. */
#main .eyebrow {
  color: #fff;
  background: linear-gradient(180deg, #4f7dff, #1a45e0);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.45), inset 0 0 0 1px rgb(255 255 255 / 0.16);
}

/* "Let's talk" goes grey where its light plays (owner, 2026-09-30): while
   Pricing (data-glow) or the form (data-live) holds the middle of the
   screen, the button wears the nav links' current-section pill (grey,
   ink type; in dark, the dark pill), so the circling blue light is the one
   blue thing there. The light itself is unchanged. Back to blue past those
   sections, and on hover, since it is still the button. The colour eases
   (the nav CTA's own transition listed only opacity and transform). */
.nav__cta {
  transition: opacity var(--dur-short) var(--ease-out), transform var(--dur-short) var(--ease-out), visibility 0s,
              background-color 300ms var(--ease-out), color 300ms var(--ease-out), box-shadow 300ms var(--ease-out);
}
.nav .nav__cta:is([data-glow], [data-live]):not(:hover) {
  --btn-bg: var(--color-pill); --btn-fg: var(--color-ink);
  box-shadow: none;
}

/* "Talk to us" turns blue once scrolled past (owner, 2026-09-30; JS sets
   .is-passed): the grey button eases into the site's blue button, its
   highlights included, over half a second. */
.btn--gray[data-turns-blue] { transition: background-color 500ms var(--ease-out), color 500ms var(--ease-out), box-shadow 500ms var(--ease-out), transform 50ms; }
.btn--gray.is-passed { --btn-bg: color(display-p3 0.0118 0.2067 0.9861); }
.btn--gray.is-passed:hover { --btn-bg: color(display-p3 0.1 0.3 1); }

/* EuroDecor plays on its own (owner, 2026-09-30): the frame is our copy of
   the site, driven by app.js; it takes no pointer, so the wheel always
   scrolls this page (letting visitors scroll inside trapped anyone passing).
   Its scrubber and knob chevrons are Redesigned's (.dip__scrub, .dip__ghost):
   upright in the gap right of the frame from 70rem, where both gaps widen
   from 24 to 56px so the frame stays centred; below that, the horizontal
   bar under the frame. */
.build__doc { pointer-events: none; }
.build__stage .dip__scrub { margin-block-start: 6px; }
@media (min-width: 70rem) {
  .triptych { gap: 56px; }
  .build__stage .dip__scrub { margin: 0; }
}

/* The scrubber knob in the chips' finish (owner, 2026-09-30): the headline
   icon's blue gradient with its light top edge and inner ring, and a soft
   drop, instead of a flat accent disc; both players, both orientations
   (gradients are physical, so the light stays on top when the bar is upright). */
.dip__scrub::-webkit-slider-thumb {
  background: linear-gradient(180deg, #4f7dff, #1a45e0);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.45), inset 0 0 0 1px rgb(255 255 255 / 0.16),
              0 2px 6px -1px rgb(10 30 160 / 0.45);
}
.dip__scrub::-moz-range-thumb {
  background: linear-gradient(180deg, #4f7dff, #1a45e0);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.45), inset 0 0 0 1px rgb(255 255 255 / 0.16),
              0 2px 6px -1px rgb(10 30 160 / 0.45);
}

/* ================================================= the hero film (2026-09-30)
   Owner's brother, after ToDesktop's hero: "their motion works are another
   level". Every pixel hand-built, one story told end to end (app.js
   heroSteps keeps the clock; every beat below is keyed to data-step, so a
   scene replays whenever its step is set again). Sizes are in cqi of the
   panel (.shot is the container); BizArch's page sets 1em = 1cqi.
   1 · We audit it (7s): the visitor's own template site, scanned; four
       findings mark their spots and name themselves; the verdict card.
   2 · We rebuild it (7.5s): BizArch's page builds itself.
   3 · We refine and launch (9.5s): two sample review notes acted on (the
       headline grows, the page turns Arabic), publishing, live.
   Under reduced motion every beat jumps to its end. Undo: this block,
   cases/hero/film.html and heroSteps in app.js (git has the stills version). */

/* step 1 · the template every business recognises: logo box, five menu
   links, a stock photo with "Welcome to Our Company", three icon boxes */
.gen {
  position: absolute; inset: 0; display: grid; grid-template-rows: 9% 1fr 24%;
  background: #fff; color: #333; font-family: Arial, Helvetica, sans-serif;
  transition: opacity 250ms;
}
.gen__bar { display: flex; align-items: center; justify-content: space-between; padding-inline: 5cqi; border-block-end: 1px solid #e6e6e6; }
.gen__logo { padding: 0.5cqi 1.4cqi; border: 1.5px solid #9aa3ad; color: #7a838d; font-size: 1.3cqi; font-weight: 700; letter-spacing: 0.1em; }
.gen__menu { display: flex; gap: 2.6cqi; }
.gen__menu i { font-style: normal; font-size: 1.25cqi; color: #555; }
.gen__menu i:first-child { color: #2a7fd4; }
.gen__hero {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.3cqi;
  background: linear-gradient(160deg, #9fb0c0, #71869b 60%, #5d7185); text-align: center; overflow: hidden;
}
.gen__pic { position: absolute; inset-block-start: 8%; inset-inline-end: 7%; inline-size: 13cqi; fill: none; stroke: rgb(255 255 255 / 0.35); stroke-width: 1.2; }
.gen__h { margin: 0; font-size: 3.6cqi; font-weight: 700; color: #fff; text-shadow: 0 1px 3px rgb(0 0 0 / 0.3); }
.gen__p { margin: 0; font-size: 1.35cqi; color: rgb(255 255 255 / 0.85); }
.gen__btn { margin-block-start: 0.6cqi; padding: 0.9cqi 2.4cqi; background: #2a7fd4; color: #fff; font-size: 1.2cqi; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }
.gen__row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3cqi; padding: 2.4cqi 7cqi; background: #f5f5f5; }
.gen__row span { display: flex; flex-direction: column; align-items: center; gap: 0.9cqi; font-size: 1.25cqi; font-weight: 700; color: #555; }
.gen__row i { inline-size: 4cqi; block-size: 4cqi; border-radius: 50%; background: #d9e6f3; box-shadow: inset 0 0 0 0.5cqi #bcd3ea; }
.shot:not([data-step="0"]) .gen { opacity: 0; }

/* scene 1 · the scan, the findings, the verdict */
.gen__scan {
  position: absolute; inset-inline: 0; inset-block-start: 0; block-size: 2px; opacity: 0;
  background: linear-gradient(90deg, transparent, #8fb8ff 30%, #fff 50%, #8fb8ff 70%, transparent);
  box-shadow: 0 0 1.6cqi 0.4cqi rgb(80 140 255 / 0.75);
}
.gen__mark {
  position: absolute; opacity: 0; border-radius: 0.8cqi; pointer-events: none;
  box-shadow: 0 0 0 1.5px #ff5a64, 0 0 1.4cqi rgb(255 90 100 / 0.45), inset 0 0 2cqi rgb(255 90 100 / 0.12);
}
/* each mark rings its target with the same gap all round, 8px at a 952px
   panel (0.84% across, 1.34% down), from the targets measured there
   (2026-10-01; they were off: the headline's cut into its top, the photo's
   smaller than the photo, "Read more" and the cards uneven) */
.gen__mark--1 { inset-inline-start: 26.31%; inset-block-start: 28.96%; inline-size: 47.37%; block-size: 12.2%; }
.gen__mark--2 { inset-inline-start: 78.94%; inset-block-start: 13.01%; inline-size: 14.89%; block-size: 23.83%; }
.gen__mark--3 { inset-inline-start: 42.66%; inset-block-start: 47.24%; inline-size: 14.67%; block-size: 8.79%; }
.gen__mark--4 { inset-inline-start: 6.28%; inset-block-start: 78.55%; inline-size: 87.44%; block-size: 18.87%; }
.gen__verdict {
  position: absolute; z-index: 2; margin: 0; opacity: 0; translate: -50% 0; white-space: nowrap;
  display: flex; align-items: center; gap: 0.8cqi; padding: 0.7cqi 1.5cqi 0.7cqi 0.7cqi; border-radius: 999px;
  background: rgb(12 14 40 / 0.86); color: #fff; font: 500 1.35cqi/1.4 var(--font-body);
  box-shadow: 0 1cqi 2.4cqi -0.8cqi rgb(0 0 0 / 0.5), inset 0 0 0 1px rgb(255 255 255 / 0.12);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.gen__verdict b { display: grid; place-items: center; inline-size: 2cqi; block-size: 2cqi; border-radius: 50%; background: #ff5a64; font-size: 1.05cqi; }
.gen__verdict--1 { inset-inline-start: 50%; inset-block-start: 41.5%; }
.gen__verdict--2 { inset-inline-start: 72%; inset-block-start: 35.5%; }
.gen__verdict--3 { inset-inline-start: 50%; inset-block-start: 57.5%; }
.gen__verdict--4 { inset-inline-start: 50%; inset-block-start: 69.5%; }
.gen__done {
  position: absolute; z-index: 3; left: 50%; inset-block-start: 65.5%; margin: 0; opacity: 0; translate: -50% -50%;
  display: grid; grid-template-columns: auto 1fr; column-gap: 1.2cqi; align-items: center;
  padding: 1.6cqi 2.4cqi 1.6cqi 1.6cqi; border-radius: 1.6cqi; background: #fff; color: #141414;
  box-shadow: 0 2.4cqi 5cqi -1.6cqi rgb(8 12 40 / 0.55), 0 0 0 1px rgb(0 0 0 / 0.06);
}
.gen__done b { grid-row: span 2; display: grid; place-items: center; inline-size: 3.6cqi; block-size: 3.6cqi; border-radius: 50%; background: #1fbf6a; color: #fff; font-size: 1.8cqi; }
.gen__done span { font: 600 1.7cqi/1.3 var(--font-body); }
.gen__done em { font: 400 1.35cqi/1.4 var(--font-body); font-style: normal; color: #656565; }

.shot[data-step="0"] .gen__scan { animation: film-scan 2200ms 200ms cubic-bezier(0.45, 0, 0.55, 1) both; }
.shot[data-step="0"] .gen__mark--1 { animation: film-mark 500ms 1000ms cubic-bezier(0.34, 1.4, 0.5, 1) both; }
.shot[data-step="0"] .gen__mark--2 { animation: film-mark 500ms 2200ms cubic-bezier(0.34, 1.4, 0.5, 1) both; }
.shot[data-step="0"] .gen__mark--3 { animation: film-mark 500ms 3400ms cubic-bezier(0.34, 1.4, 0.5, 1) both; }
.shot[data-step="0"] .gen__mark--4 { animation: film-mark 500ms 4600ms cubic-bezier(0.34, 1.4, 0.5, 1) both; }
.shot[data-step="0"] .gen__verdict--1 { animation: film-verdict 1200ms 1050ms both; }
.shot[data-step="0"] .gen__verdict--2 { animation: film-verdict 1200ms 2250ms both; }
.shot[data-step="0"] .gen__verdict--3 { animation: film-verdict 1200ms 3450ms both; }
.shot[data-step="0"] .gen__verdict--4 { animation: film-verdict 1200ms 4650ms both; }
.shot[data-step="0"] .gen__done { animation: film-card 600ms 5850ms cubic-bezier(0.2, 0.9, 0.3, 1.15) both; }
@keyframes film-scan { 0% { opacity: 0; inset-block-start: 0; } 8% { opacity: 1; } 90% { opacity: 1; } 100% { opacity: 0; inset-block-start: 100%; } }
@keyframes film-mark { from { opacity: 0; scale: 1.12; } to { opacity: 1; scale: 1; } }
@keyframes film-verdict { 0% { opacity: 0; translate: -50% 0.8cqi; } 15%, 82% { opacity: 1; translate: -50% 0; } 100% { opacity: 0; translate: -50% -0.4cqi; } }
@keyframes film-card { from { opacity: 0; translate: -50% -40%; scale: 0.94; } to { opacity: 1; translate: -50% -50%; scale: 1; } }

/* scenes 2 and 3 · BizArch's page, hand-built (cases/hero/film.html) */
.bz {
  position: absolute; inset: 0; overflow: hidden; opacity: 0;
  background: #fff; color: #0f172a; font: 400 1cqi/1.35 var(--font-body);
}
.bz img { display: block; }
.bz p, .bz h3, .bz ul { margin: 0; padding: 0; }
.bz i { font-style: normal; }
.bz__nav { position: absolute; inset: 1.4em 5.5em auto 5.5em; block-size: 4.4em; display: flex; align-items: center; gap: 1.4em; }
.bz__logo { display: flex; align-items: center; gap: 0.6em; }
.bz__logo img { block-size: 2.4em; inline-size: auto; }
.bz__logo b { font: 700 2.1em/1 'Space Grotesk', var(--font-body); color: #0369a1; letter-spacing: -0.01em; }
.bz__menu { display: flex; gap: 2.2em; margin-inline: auto; font-size: 1.25em; color: #3f4e66; }
.bz__lang { padding: 0.55em 1.2em; border-radius: 2em; box-shadow: inset 0 0 0 1px #e2e8f0; font-size: 1.15em; color: #3f4e66; }
.bz__demo { padding: 0.8em 1.6em; border-radius: 2em; background: #0f172a; color: #fff; font-size: 1.2em; font-weight: 600; }
.bz__main { position: absolute; inset-inline-start: 11em; inset-block-start: 10.5em; inline-size: 44em; }
.bz__pill { display: inline-flex; align-items: center; gap: 0.6em; padding: 0.45em 1.1em 0.45em 0.5em; border-radius: 2em; box-shadow: inset 0 0 0 1px #e2e8f0, 0 0.3em 0.8em -0.4em rgb(15 23 42 / 0.2); font-size: 1.05em; font-weight: 500; }
.bz__gem { inline-size: 1.3em; block-size: 1.3em; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #a7f3d0, #38bdf8 60%, #0369a1); }
.bz__h1 { margin-block: 0.4em 0.45em !important; font: 700 3.9em/1.04 'Space Grotesk', var(--font-body); letter-spacing: -0.025em; color: #0f172a; }
.bz__h1 .w { display: inline-block; }
.bz__ticks { list-style: none; display: grid; gap: 0.7em; }
.bz__ticks li { position: relative; padding-inline-start: 1.7em; font-size: 1.15em; color: #3f4e66; }
.bz__ticks li::before { content: "✓"; position: absolute; inset-inline-start: 0; color: #0369a1; font-weight: 700; }
.bz__ticks b { color: #0f172a; font-weight: 700; }
.bz__cta { display: flex; align-items: center; gap: 1.3em; margin-block-start: 2.3em; }
.bz__btn { padding: 1em 2em; border-radius: 0.7em; background: #0f172a; color: #fff; font-size: 1.25em; font-weight: 600; box-shadow: 0 0.8em 1.6em -0.8em rgb(15 23 42 / 0.6); }
.bz__note { font-size: 1em; color: #64748b; }
.bz__kick { margin-block-start: 2.6em !important; font: 500 0.85em/1 var(--font-mono); letter-spacing: 0.18em; text-transform: uppercase; color: #64748b; }
.bz__chips { display: flex; flex-wrap: wrap; gap: 0.7em; margin-block-start: 1em; }
.bz__chips i { padding: 0.5em 1.1em; border-radius: 2em; box-shadow: inset 0 0 0 1px #e2e8f0; font-size: 1.1em; font-weight: 500; }
.bz__chips i.on { box-shadow: inset 0 0 0 1.5px #0369a1; color: #0369a1; background: #f0f9ff; }
/* BizArch ERP's dashboard as it is now (owner's screenshots, 2026-10-01):
   a midnight sidebar whose active item is a pale tab joined to the board
   by two inverted corners; search, quick actions in tinted tiles, the date
   range, then stat cards with round tinted icons and the riyal sign. The
   Arabic page gets the Arabic app, right to left (sidebar on the right). */
.bz__dash {
  position: absolute; inset-inline-start: 56em; inset-block-start: 13em; inline-size: 48em; block-size: 33em;
  display: flex; border-radius: 1em; overflow: hidden; background: #050816; --pale: #f8fafc;
  box-shadow: 0 2.4em 4.8em -2em rgb(15 23 42 / 0.4), 0 0 0 1px #1e293b;
  -webkit-mask-image: linear-gradient(90deg, #000 78%, transparent); mask-image: linear-gradient(90deg, #000 78%, transparent);
}
.bz__dash svg { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.bz__side { flex: none; inline-size: 11em; display: flex; flex-direction: column; gap: 0.2em; padding-block: 1em; padding-inline-start: 0.7em; color: #cbd5e1; }
.bz__app { display: flex; align-items: center; gap: 0.55em; padding-inline-end: 0.8em; margin-block-end: 0.7em !important; font-size: 0.95em; font-weight: 600; color: #fff; }
.bz__app img { inline-size: 1.8em; block-size: 1.8em; border-radius: 0.4em; }
.bz__chev { margin-inline-start: auto; color: #94a3b8; font-weight: 400; }
.bz__side i { position: relative; display: flex; align-items: center; gap: 0.6em; padding: 0.55em 0.7em; font-size: 0.82em; border-start-start-radius: 0.7em; border-end-start-radius: 0.7em; }
.bz__side i svg { flex: none; inline-size: 1.25em; block-size: 1.25em; }
.bz__side em { margin-inline-start: auto; padding-inline-end: 0.5em; font-style: normal; color: #94a3b8; }
.bz__side i.on { background: var(--pale); color: #0369a1; font-weight: 600; }
.bz__side i.on::before, .bz__side i.on::after {   /* the inverted corners into the board */
  content: ""; position: absolute; inset-inline-end: 0; inline-size: 0.8em; block-size: 0.8em;
  background: radial-gradient(circle at 0 0, transparent 0.8em, var(--pale) 0.82em);
}
.bz__side i.on::before { inset-block-start: -0.8em; }
.bz__side i.on::after { inset-block-end: -0.8em; background: radial-gradient(circle at 0 100%, transparent 0.8em, var(--pale) 0.82em); }
.bz--ar .bz__side i.on::before { background: radial-gradient(circle at 100% 0, transparent 0.8em, var(--pale) 0.82em); }
.bz--ar .bz__side i.on::after { background: radial-gradient(circle at 100% 100%, transparent 0.8em, var(--pale) 0.82em); }
.bz__board { flex: 1; min-inline-size: 0; padding: 1em 1.2em; background: var(--pale); border-start-start-radius: 1.3em; border-end-start-radius: 1.3em; color: #0f172a; }
.bz__search, .bz__finds span { display: flex; align-items: center; gap: 0.5em; padding: 0.5em 0.8em; border-radius: 0.6em; background: #fff; box-shadow: inset 0 0 0 1px #e2e8f0; color: #64748b; white-space: nowrap; }
.bz__search { font-size: 0.8em; }
.bz__search svg, .bz__finds svg { flex: none; inline-size: 1.1em; block-size: 1.1em; }
.bz__search kbd { margin-inline-start: auto; padding: 0.1em 0.4em; border-radius: 0.3em; box-shadow: inset 0 0 0 1px #e2e8f0; font: 0.8em var(--font-mono); }
.bz__title { margin-block: 0.9em 0.7em !important; font-size: 0.85em; color: #64748b; }
.bz__title b { margin-inline-end: 0.4em; font-size: 1.4em; color: #0f172a; }
.bz__finds { display: grid; grid-template-columns: 2fr 1fr; gap: 0.5em; font-size: 0.75em; }
.bz__acts { display: flex; gap: 0.5em; margin-block-start: 0.6em; }
.bz__acts i { display: flex; align-items: center; gap: 0.55em; flex: none; padding: 0.5em 0.9em 0.5em 0.55em; border-radius: 0.7em; background: #fff; box-shadow: inset 0 0 0 1px #e2e8f0; font-size: 0.75em; font-weight: 500; white-space: nowrap; }
.bz__acts s { display: grid; place-items: center; inline-size: 2em; block-size: 2em; border-radius: 0.55em; }
.bz__acts s svg { inline-size: 1.15em; block-size: 1.15em; }
.bz__act--blue s { background: #e0f2fe; color: #0369a1; }   .bz__act--violet s { background: #ede9fe; color: #7c3aed; }
.bz__act--green s { background: #dcfce7; color: #16a34a; }  .bz__act--amber s { background: #fef3c7; color: #d97706; }
.bz__act--red s { background: #fee2e2; color: #dc2626; }
.bz__range { display: flex; gap: 0.15em; inline-size: max-content; margin-block-start: 0.7em; padding: 0.3em; border-radius: 0.7em; background: #fff; box-shadow: inset 0 0 0 1px #e2e8f0; }
.bz__range i { padding: 0.35em 0.65em; border-radius: 0.5em; font-size: 0.7em; color: #334155; white-space: nowrap; }
.bz__range i.on { background: #0b5f99; color: #fff; }
.bz__lab { margin-block: 0.9em 0.5em !important; font: 600 0.62em/1 var(--font-mono); letter-spacing: 0.1em; text-transform: uppercase; color: #64748b; }
.bz__stats, .bz__pnl { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.5em; }
.bz__stats div, .bz__pnl div { display: grid; grid-template-columns: auto 1fr; align-content: start; column-gap: 0.5em; padding: 0.65em 0.7em; border-radius: 0.7em; background: #fff; box-shadow: inset 0 0 0 1px #e2e8f0; }
.bz__stats s, .bz__pnl s { grid-row: span 2; display: grid; place-items: center; inline-size: 1.7em; block-size: 1.7em; border-radius: 50%; background: #e0f2fe; color: #0369a1; }
.bz__pnl s { background: #ede9fe; color: #7c3aed; }
.bz__stats s svg, .bz__pnl s svg { inline-size: 1em; block-size: 1em; }
.bz__stats small, .bz__pnl small { font-size: 0.6em; letter-spacing: 0.06em; text-transform: uppercase; color: #64748b; line-height: 1.3; }
.bz__stats b, .bz__pnl b { display: flex; align-items: center; gap: 0.2em; font: 600 1.1em/1.35 'Space Grotesk', var(--font-body); font-variant-numeric: tabular-nums; }
.bz__dash b.bz__up { color: #15803d; }
.bz__sar { flex: none; inline-size: 0.62em; block-size: 0.7em; stroke-width: 1.5 !important; }
.bz--ar .bz__dash small, .bz--ar .bz__lab { font-family: 'IBM Plex Sans Arabic', var(--font-body); letter-spacing: 0; text-transform: none; }
.bz--ar .bz__lab { font-size: 0.72em; font-weight: 600; }
.bz--ar .bz__stats small, .bz--ar .bz__pnl small { font-size: 0.66em; }
.bz--ar .bz__acts i { padding: 0.5em 0.55em 0.5em 0.9em; }
.bz--ar .bz__stats b, .bz--ar .bz__pnl b { justify-content: flex-end; }
.bz__trust { position: absolute; inset-inline: 11em; inset-block-start: 55.5em; display: flex; align-items: center; justify-content: space-between; gap: 2em; }
.bz__trust span { font: 500 0.85em/1 var(--font-mono); letter-spacing: 0.16em; text-transform: uppercase; color: #64748b; white-space: nowrap; }
.bz__trust img { block-size: 2.2em; inline-size: auto; filter: grayscale(1); opacity: 0.55; }
.bz__trust img.lockup { block-size: 3.1em; }   /* their stacked lockups: 40px to the row's 28 (2026-10-03) */
/* the Arabic page: BizArch's own Arabic copy, mirrored; the dashboard stays the app it is */
.bz--ar { font-family: 'IBM Plex Sans Arabic', var(--font-body); }
.bz--ar .bz__h1 { font: 700 4.4em/1.2 'IBM Plex Sans Arabic', var(--font-body); letter-spacing: 0; }
.bz--ar .bz__ticks li { font-size: 1.2em; }
.bz--ar .bz__trust span { font-family: 'IBM Plex Sans Arabic', var(--font-body); letter-spacing: 0; font-size: 1em; }
.bz--ar .bz__kick { font-family: 'IBM Plex Sans Arabic', var(--font-body); letter-spacing: 0; font-size: 1em; }
.bz--ar .bz__dash { inset-inline-start: auto; left: -4em; -webkit-mask-image: linear-gradient(270deg, #000 78%, transparent); mask-image: linear-gradient(270deg, #000 78%, transparent); }

/* scene 2 · it builds itself */
.shot[data-step="1"] .bz--en, .shot[data-step="2"] .bz--en { opacity: 1; }
.shot[data-step="1"] .bz--en :is(.bz__trust, .bz__nav, .bz__pill, .bz__h1 .w, .bz__ticks li, .bz__cta, .bz__kick, .bz__chips i, .bz__side > *, .bz__search, .bz__title, .bz__finds span, .bz__acts i, .bz__range, .bz__lab, .bz__stats div, .bz__pnl div) {
  animation: film-in 520ms var(--at, 0ms) cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.shot[data-step="1"] .bz--en .bz__dash { animation: film-rise 800ms 2900ms cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.bz--en .bz__nav { --at: 150ms; }
.bz--en .bz__pill { --at: 500ms; }
.bz--en .bz__h1 .w:nth-of-type(1) { --at: 800ms; }  .bz--en .bz__h1 .w:nth-of-type(2) { --at: 920ms; }
.bz--en .bz__h1 .w:nth-of-type(3) { --at: 1040ms; } .bz--en .bz__h1 .w:nth-of-type(4) { --at: 1160ms; }
.bz--en .bz__h1 .w:nth-of-type(5) { --at: 1280ms; } .bz--en .bz__h1 .w:nth-of-type(6) { --at: 1400ms; }
.bz--en .bz__h1 .w:nth-of-type(7) { --at: 1520ms; }
.bz--en .bz__ticks li:nth-child(1) { --at: 1950ms; } .bz--en .bz__ticks li:nth-child(2) { --at: 2200ms; } .bz--en .bz__ticks li:nth-child(3) { --at: 2450ms; }
.bz--en .bz__cta { --at: 2750ms; }
.bz--en .bz__kick { --at: 3050ms; }
.bz--en .bz__chips i:nth-child(1) { --at: 3150ms; } .bz--en .bz__chips i:nth-child(2) { --at: 3210ms; } .bz--en .bz__chips i:nth-child(3) { --at: 3270ms; }
.bz--en .bz__chips i:nth-child(4) { --at: 3330ms; } .bz--en .bz__chips i:nth-child(5) { --at: 3390ms; } .bz--en .bz__chips i:nth-child(6) { --at: 3450ms; }
.bz--en .bz__chips i:nth-child(7) { --at: 3510ms; } .bz--en .bz__chips i:nth-child(8) { --at: 3570ms; } .bz--en .bz__chips i:nth-child(9) { --at: 3630ms; }
.bz--en .bz__side > :nth-child(1) { --at: 3150ms; } .bz--en .bz__side > :nth-child(2) { --at: 3200ms; } .bz--en .bz__side > :nth-child(3) { --at: 3250ms; } .bz--en .bz__side > :nth-child(4) { --at: 3300ms; } .bz--en .bz__side > :nth-child(5) { --at: 3350ms; } .bz--en .bz__side > :nth-child(6) { --at: 3400ms; } .bz--en .bz__side > :nth-child(7) { --at: 3450ms; } .bz--en .bz__side > :nth-child(8) { --at: 3500ms; } .bz--en .bz__side > :nth-child(9) { --at: 3550ms; } .bz--en .bz__side > :nth-child(10) { --at: 3600ms; }
.bz--en .bz__search { --at: 3250ms; } .bz--en .bz__title { --at: 3330ms; } .bz--en .bz__finds span:nth-child(1) { --at: 3390ms; } .bz--en .bz__finds span:nth-child(2) { --at: 3430ms; }
.bz--en .bz__acts i:nth-child(1) { --at: 3450ms; } .bz--en .bz__acts i:nth-child(2) { --at: 3510ms; } .bz--en .bz__acts i:nth-child(3) { --at: 3570ms; } .bz--en .bz__acts i:nth-child(4) { --at: 3630ms; } .bz--en .bz__acts i:nth-child(5) { --at: 3690ms; }
.bz--en .bz__range { --at: 3600ms; } .bz--en .bz__lab { --at: 3650ms; }
.bz--en .bz__stats div:nth-child(1) { --at: 3700ms; } .bz--en .bz__stats div:nth-child(2) { --at: 3770ms; } .bz--en .bz__stats div:nth-child(3) { --at: 3840ms; } .bz--en .bz__stats div:nth-child(4) { --at: 3910ms; } .bz--en .bz__stats div:nth-child(5) { --at: 3980ms; } .bz--en .bz__stats div:nth-child(6) { --at: 4050ms; }
.bz--en .bz__pnl div:nth-child(1) { --at: 4150ms; } .bz--en .bz__pnl div:nth-child(2) { --at: 4220ms; } .bz--en .bz__pnl div:nth-child(3) { --at: 4290ms; } .bz--en .bz__pnl div:nth-child(4) { --at: 4360ms; }
.bz--en .bz__trust { --at: 4500ms; }
@keyframes film-in { from { opacity: 0; translate: 0 0.9em; filter: blur(0.25em); } to { opacity: 1; translate: 0 0; filter: blur(0); } }
@keyframes film-rise { from { opacity: 0; translate: 0 3em; scale: 0.97; } to { opacity: 1; translate: 0 0; scale: 1; } }

/* the rebuild tag sits at the foot: at the top it covered BizArch's menu */
.shot__day { inset-block-start: auto; inset-block-end: 3cqi; translate: -50% 6px; z-index: 4; }

/* scene 3 · review, Arabic, publish, live */
.shot[data-step="2"] .bz--en .bz__h1 { animation: film-grow 700ms 1500ms cubic-bezier(0.3, 0.8, 0.3, 1) both; }
.shot[data-step="2"] .bz--en { animation: film-out 380ms 3900ms cubic-bezier(0.4, 0, 1, 1) both; }
.shot[data-step="2"] .bz--ar { animation: film-flip 600ms 4230ms cubic-bezier(0.2, 0.8, 0.2, 1) both; }
@keyframes film-grow { from { font-size: 3.9em; } to { font-size: 4.3em; } }
@keyframes film-out { from { opacity: 1; translate: 0 0; } to { opacity: 0; translate: -2em 0; } }
@keyframes film-flip { from { opacity: 0; translate: 2em 0; } to { opacity: 1; translate: 0 0; } }

.rv {
  position: absolute; z-index: 4; opacity: 0; display: flex; align-items: center; gap: 1cqi;
  padding: 0.9cqi 1.3cqi 0.9cqi 0.9cqi; border-radius: 1.4cqi 1.4cqi 1.4cqi 0.3cqi; background: #fff; color: #141414;
  box-shadow: 0 1.6cqi 3.6cqi -1.2cqi rgb(8 12 40 / 0.45), 0 0 0 1px rgb(0 0 0 / 0.06);
}
.rv__av { display: grid; place-items: center; inline-size: 2.8cqi; block-size: 2.8cqi; border-radius: 50%; background: linear-gradient(180deg, #4f7dff, #1a45e0); color: #fff; font: 600 1.3cqi/1 var(--font-body); }
.rv__body { display: flex; flex-direction: column; font: 500 1.4cqi/1.35 var(--font-body); }
.rv__body small { font: 500 0.95cqi/1.3 var(--font-mono); letter-spacing: 0.04em; text-transform: uppercase; color: #8a8a8a; }
.rv__done { display: grid; place-items: center; inline-size: 2.2cqi; block-size: 2.2cqi; border-radius: 50%; background: #1fbf6a; color: #fff; font-size: 1.2cqi; opacity: 0; scale: 0.5; }
.rv--1 { inset-inline-start: 49%; inset-block-start: 38%; }
.rv--2 { inset-inline-start: 57%; inset-block-start: 11%; }
.shot[data-step="2"] .rv--1 { animation: film-note 3500ms 300ms both; }   /* the first note 0.2s sooner (2026-10-01) */
.shot[data-step="2"] .rv--2 { animation: film-note 2300ms 2750ms both; }
.shot[data-step="2"] .rv--1 .rv__done { animation: film-done 400ms 2250ms cubic-bezier(0.34, 1.6, 0.5, 1) both; }
.shot[data-step="2"] .rv--2 .rv__done { animation: film-done 400ms 4350ms cubic-bezier(0.34, 1.6, 0.5, 1) both; }
@keyframes film-note { 0% { opacity: 0; translate: 0 1cqi; scale: 0.96; } 12%, 86% { opacity: 1; translate: 0 0; scale: 1; } 100% { opacity: 0; translate: 0 -0.6cqi; } }
@keyframes film-done { to { opacity: 1; scale: 1; } }

/* the address bar publishes, then the page is live (app.js sets data-pub, data-live) */
@property --pub { syntax: "<percentage>"; inherits: false; initial-value: 0%; }
.shot[data-pub] .shot__url {
  background: linear-gradient(90deg, rgb(61 220 132 / 0.42) var(--pub), rgb(255 255 255 / 0.08) var(--pub));
  animation: film-pub 1500ms linear both;
}
@keyframes film-pub { to { --pub: 100%; } }
.shot[data-step="2"]:not([data-live]) .shot__state::before { display: none; }
.shot[data-live] .shot__state::before {
  content: ""; inline-size: 7px; block-size: 7px; border-radius: 50%;
  background: #3ddc84; box-shadow: 0 0 8px #3ddc84;
}
.shot[data-step="2"]:not([data-live]) ~ .shot__compare { opacity: 0; translate: 0 8px; pointer-events: none; }


@media (prefers-reduced-motion: reduce) {
  .shot .gen *, .shot .bz, .shot .bz *, .shot .rv, .shot .rv *, .shot[data-pub] .shot__url, .shot[data-live] .shot__view {
    animation-duration: 1ms !important; animation-delay: 0s !important;
  }
  .shot .bz { transition: none; }
}

/* ================================================= the hero film on phones (2026-09-30)
   Owner: the landscape film shrunk to a postage stamp on a phone (text at
   3–4px). As ToDesktop recomposes its hero for mobile, the panel turns tall
   (10:19) and each scene is laid out as a real 375px-wide phone page, then
   scaled to the panel (app.js sets --k and --vh on .shot__view): the
   template site's phone layout; BizArch's real mobile hero (measured from
   cases/bizarch/after at 375: no dashboard on phones, its own chip set);
   and for the Arabic turn, the real capture of their Arabic phone page.
   No desktop card and no handset at the end: the panel is the phone. */
.gen__burger, .bz__globe, .bz__burger, .bz__chips--m, .bz-arshot { display: none; }
@media (max-width: 40rem) {
  .shot__view { aspect-ratio: 10 / 19; }
  .gen, .bz {
    inset: 0 auto auto 0; inline-size: 375px; block-size: var(--vh, 712px);
    transform: scale(var(--k, 0.9)); transform-origin: 0 0;
  }

  /* scene 1 · the template, phone layout */
  .gen { grid-template-rows: 58px 380px 1fr; }
  .gen__bar { padding-inline: 18px; }
  .gen__logo { padding: 4px 10px; font-size: 12px; }
  .gen__menu { display: none; }
  .gen__burger { display: block; inline-size: 22px; block-size: 14px; border-block: 2px solid #555; background: linear-gradient(#555, #555) center / 100% 2px no-repeat; }
  .gen__hero { gap: 12px; padding-inline: 30px; }
  .gen__pic { inset-block-start: 18px; inset-inline-end: 18px; inline-size: 60px; }
  .gen__h { font-size: 28px; line-height: 1.2; }
  .gen__p { font-size: 13px; }
  .gen__btn { margin-block-start: 0; padding: 10px 22px; font-size: 12px; }
  .gen__row { gap: 10px; padding: 26px 16px; }
  .gen__row span { gap: 8px; font-size: 12px; }
  .gen__row i { inline-size: 40px; block-size: 40px; box-shadow: inset 0 0 0 5px #bcd3ea; }
  .gen__mark { border-radius: 8px; }
  /* each mark rings its target with the same 8px all round, in the phone
     page's own px (owner's brother, 2026-10-01: in % of a panel whose height
     varies they sat off-centre, "Read more" worst: 3px above, 10px below).
     Targets, measured: headline 30,161.5 315x67; photo 297,76 60x60;
     "Read more" 125.6,295 124x39.5; the three cards 16–359 x 464 to the
     page's foot less 26. */
  .gen__mark--1 { inset-inline-start: 22px; inset-block-start: 153.5px; inline-size: 331px; block-size: 83px; }
  .gen__mark--2 { inset-inline-start: 289px; inset-block-start: 68px; inline-size: 76px; block-size: 76px; }
  .gen__mark--3 { inset-inline-start: 117.5px; inset-block-start: 287px; inline-size: 140px; block-size: 55.5px; }
  .gen__mark--4 { inset-inline: 8px; inset-block: 456px 18px; inline-size: auto; block-size: auto; }
  .gen__verdict { gap: 8px; padding: 6px 14px 6px 6px; font-size: 13px; }
  .gen__verdict b { inline-size: 20px; block-size: 20px; font-size: 11px; }
  .gen__verdict--1 { inset-block-start: 36.5%; }
  .gen__verdict--2 { inset-inline-start: 39%; inset-block-start: 14%; }
  .gen__verdict--3 { inset-block-start: 49.5%; }
  .gen__verdict--4 { inset-block-start: 57.5%; }
  .gen__done { inset-block-start: 55%; column-gap: 12px; padding: 14px 18px 14px 14px; border-radius: 14px; white-space: nowrap; }
  .gen__done b { inline-size: 36px; block-size: 36px; font-size: 17px; }
  .gen__done span { font-size: 15px; }
  .gen__done em { font-size: 12px; }

  /* scenes 2 and 3 · BizArch's phone page, English */
  .bz { font-size: 16px; }
  .bz__nav { inset: 0 20px auto 20px; block-size: 64px; gap: 0; }
  .bz__logo img { block-size: 26px; }
  .bz__logo b { font-size: 19px; }
  .bz__menu, .bz__lang, .bz__demo, .bz__dash, .bz__chips:not(.bz__chips--m) { display: none; }
  .bz__globe {
    display: block; margin-inline-start: auto; inline-size: 38px; block-size: 38px; border-radius: 50%;
    background: #f1f5f9; box-shadow: inset 0 0 0 1px #e2e8f0;
    background-image: radial-gradient(circle, transparent 5.5px, #0f172a 5.5px 7px, transparent 7px);
  }
  .bz__burger { display: block; margin-inline-start: 14px; inline-size: 22px; block-size: 14px; border-block: 2px solid #0f172a; background: linear-gradient(#0f172a, #0f172a) center / 100% 2px no-repeat; }
  .bz__main { inset-inline-start: 20px; inset-block-start: 102px; inline-size: 335px; }
  .bz__pill { gap: 7px; padding: 7px 12px 7px 7px; font-size: 12px; }
  .bz__gem { inline-size: 18px; block-size: 18px; }
  .bz__h1 { margin-block: 22px 16px !important; font-size: 34px; line-height: 1.04; }
  .bz__ticks { gap: 12px; }
  .bz__ticks li { padding-inline-start: 26px; font-size: 15px; line-height: 1.45; }
  .bz__cta { gap: 14px; margin-block-start: 26px; }
  .bz__btn { flex: none; padding: 18px 32px; border-radius: 10px; font-size: 15.5px; white-space: nowrap; }
  .bz__note { font-size: 12px; }
  .bz__kick { margin-block-start: 28px !important; font-size: 10.5px; letter-spacing: 0.12em; }
  .bz__chips--m { display: flex; gap: 6px; margin-block-start: 10px; }
  .bz__chips--m i { padding: 5px 10px; font-size: 11px; }
  .bz__trust { inset-inline: 20px; inset-block-start: 648px; flex-wrap: wrap; justify-content: center; gap: 12px 22px; }
  .bz__trust span { flex-basis: 100%; text-align: center; font-size: 10.5px; }
  .bz__trust img { block-size: 26px; }
  .bz__trust img.lockup { block-size: 36px; }
  .bz__trust img:nth-of-type(n + 4) { display: none; }

  /* scene 3 · the headline grows on the phone page too, then the real Arabic phone page */
  .shot[data-step="2"] .bz--en .bz__h1 { animation-name: film-grow-m; }
  @keyframes film-grow-m { from { font-size: 34px; letter-spacing: -0.025em; } to { font-size: 36px; letter-spacing: -0.04em; } }
  .bz--ar { display: none; }
  .bz-arshot { display: block; position: absolute; inset: 0 0 auto 0; z-index: 1; inline-size: 100%; block-size: auto; opacity: 0; }
  .shot[data-step="2"] .bz-arshot { animation: film-flip 600ms 4230ms cubic-bezier(0.2, 0.8, 0.2, 1) both; }
  .rv { gap: 8px; padding: 8px 12px 8px 8px; border-radius: 14px 14px 14px 4px; }
  .rv__av { inline-size: 26px; block-size: 26px; font-size: 12px; }
  .rv__body { font-size: 12.5px; }
  .rv__body small { font-size: 9px; }
  .rv__done { inline-size: 20px; block-size: 20px; font-size: 11px; }
  .rv--1 { inset-inline-start: 8%; inset-block-start: 37%; }
  .rv--2 { inset-inline-start: auto; inset-inline-end: 4%; inset-block-start: 10%; }

  /* the end: the panel is the phone, so no handset; the way down sits centred */
  .shot__compare { inset-block-end: 0; padding: 7px 16px; }
}
@media (max-width: 40rem) and (prefers-reduced-motion: reduce) {
  .shot .bz-arshot { animation-duration: 1ms !important; animation-delay: 0s !important; }
}

/* Services on short laptop screens (owner, 2026-09-30, at 1440 × 718): with
   the tabs just under the nav the card ran ~12px past the window. Up to
   820px tall: the card 896 → 880px wide (16:10 kept; every drawing scales
   with it, and at 880 every card's text keeps its exact line breaks, while
   below that the AI agents line wraps), and the gap under the tabs 40 → 22px.
   Together 28px, so the card sits whole with room under it.
   2026-10-06 (owner's brother, at 1440 × ~708): scrolled to the card's foot,
   the tabs met the floating nav. Under ~743px tall the card now also takes
   its width from the window's height (16:10), so the nav (71px), ~40px of
   air, the tabs (66px to the card) and the card with 16px under it all fit:
   880 → ~824px at 708. The drawings scale (cqi) and so does the text
   (--card-z, app.js), so every line breaks exactly as at 880. Not below
   40rem: under ~590px tall nothing fits anyway. */
@media (min-width: 60.0625rem) and (max-height: 820px) {
  .more { --card-w: min(55rem, 84vw, max(40rem, calc((100svh - 193px) * 1.6))); }
  .more__tabs { padding-block-end: 14px; margin-block-end: 8px; }   /* 14px still holds the pill's shadow (4px + 14px blur, faint at the tail) */
}

/* ================================================= Distribution: the ending (2026-10-01)
   Cloned from ToDesktop's scene 3, "Ensure smooth distribution" (owner:
   "exact same… in all aspects including the motions"). Measured from their
   page at 1440 wide (their CSS, markup and a class-by-class timeline);
   their numbers are kept as they are, in units of their 968px stage: .dist
   sets 1em to 1/968 of the panel's width, so every size below is theirs.
   The art is our own drawing (circuit, devices, wallpapers), not their
   images, and what's distributed is ours: the hero's Layoutics icon feeds
   the board, the board carries BizArch's site, the devices boot onto it.
     the panel   at "Publishing…" (data-pub) the window melts into the blue
                 and the page glides into the board (paced, not their 150ms
                 cut: see "The way in" below)
     the stage   icon box 80 at 12 (breathing, 2.25s) · stem · board 356×208
                 at 140: three glass layers, a conic light orbiting the inner
                 frame (6s) with a blurred copy under it, the chip 320×172
                 with circuit traces, three pulsing cores (1.5s) and the
                 site · traces out of the board to three slots of 262, 63
                 apart, each with a glass connector and dot · every trace a
                 10% white line with a light streak running it, travelling
                 the first half of its loop and resting the second (2–5s,
                 staggered), as theirs
     the devices data-boot from app.js, on their own offsets and gaps,
                 after the stage has built (laptop opens 3600, done 5082;
                 phone 3626 / 5208; tablet 3675 / 4180). Opening is their lid: rotate3d(-1,0,0,
                 91deg) → 0 over 1s in 1550 perspective, hinged at the foot,
                 the hinge strip narrowing 100 → 92%; the phone and tablet
                 stand up the same way. Then a dark boot screen with the
                 site's icon in a ring of orbiting light (2s); on done it
                 blows out (1.1x, blur, 150ms), the wallpaper comes up from
                 0.9x and blur, and the site lands 400ms later.
   The lights loop for as long as the frame rests, as theirs (this replaced
   our "one lap, then rest" rule); they pause off screen (data-idle).
   On phones: the middle column and the phone alone. History, the same day: a
   Layoutics chip with routed traces ("awful… unbalanced… forced"), then a
   glass stage round the icon, both superseded by this. */
/* The way in (owner, 2026-10-01: their 150ms cut read "fast and
   flickery"; paced like Apple's, in his order): every entrance is declared
   on the playing state only, so a replay resets at once. ms after
   "Publishing…":
     0–1200     the window's glass and address bar dissolve (900ms) while the
                page itself glides and shrinks into the board's slot, whole
                (rounding its corners as it lands); at 1250 the board's own
                copy takes over, pixel for pixel
     300–1100   the board's glass forms round it
     1200–1900  the circuit draws out from the page; the cores light (1300+)
     1600–2200  the stem draws up from the board
     2000–2800  the icon comes up into its box
     2800–3600  the traces draw down to the devices (staggered 60ms)
     3300       the slots, connectors and closed devices fade in
     3600       the devices open, on ToDesktop's own offsets and gaps (app.js)
   Each light starts once its line is drawn; Live at 5.4s. */
.dist {
  position: absolute; inset: 0; z-index: 2; pointer-events: none; opacity: 0;
  font-size: calc((100cqi - 16px) / 968);   /* 1em = 1/968 of the panel */
}
.shot:is([data-pub], [data-live]) .dist { opacity: 1; }
.shot:is([data-pub], [data-live]) { background-color: transparent; box-shadow: inset 0 0 0 1px transparent, 0 40px 80px -30px transparent; transition: background-color 900ms ease, box-shadow 900ms ease; }
.shot:is([data-pub], [data-live]) .shot__bar > * { opacity: 0; transition: opacity 700ms ease; }
.shot:is([data-pub], [data-live]) .shot__view { background-color: transparent; transition: background-color 900ms ease; }
.bz--ar, .bz-arshot { clip-path: inset(0 0 0 0 round 0px); }
.shot:is([data-pub], [data-live]) :is(.bz--ar, .bz-arshot) {
  z-index: 3; transform-origin: 0 0; animation: dist-hand 1250ms steps(1, end) both;
  transition: transform 1200ms cubic-bezier(0.65, 0, 0.35, 1), clip-path 1200ms cubic-bezier(0.65, 0, 0.35, 1);
}
/* the whole page lands on the slot: 240x150 at 364,169 of the 968x605 stage */
.shot:is([data-pub], [data-live]) .bz--ar { transform: translate(37.603%, 27.934%) scale(0.24793); clip-path: inset(0 0 0 0 round calc((100cqi - 16px) / 968 * 24.2)); }
/* phones: their phone page, 0.64x, its top 150 on the slot (67.5,219 of the 375-wide stage) */
.shot:is([data-pub], [data-live]) .bz-arshot { transform: translate(18%, 26.995%) scale(0.64); clip-path: inset(0 0 71.11% 0 round calc((100cqi - 10px) / 375 * 9.375)); }
@keyframes dist-hand { from { opacity: 1; } to { opacity: 0; } }
/* phones (owner, 2026-10-01: the phone page cropped in the wide board was
   "a big L", and the work happens on a desktop): the same stage, its
   middle column only (the view crops the rest). The phone page they've
   watched glides into the board and, as it lands, cross-fades into the
   desktop page (a capture: the phone styles would restyle a live copy);
   then the two devices apart (owner's sketch, 2026-10-01): the laptop
   (1x) on the left, the phone (0.806x, so the same height) on the right,
   16 apart, the pair centred; the stem's line carries straight on down
   the centre, out of the board, splits into a bar and drops the same
   length to each connector (owner: one axis, icon to devices); the arms
   are equal too, the laptop's connector set off its centre to mirror the
   phone's. The stage sits centred in the panel (frame 50 down). */
@media (max-width: 40rem) {
  .dist { font-size: calc((100cqi - 10px) / 375); }
  .dist .dist__frame { inset-block-start: 50em; }
  .dist__wires path:is(:nth-child(2), :nth-child(3), :nth-child(4)) { display: none; }
  .dist .dist__wires path:is(:nth-child(5), :nth-child(6)) { display: inline; }
  .dist .dev--tablet, .dist .dev__slot { display: none; }
  .shot .dist .bz.bz { display: none; }
  .dist :is(.dist__site, .dev__win) .bzd { display: block; }
  .dist .dist__devs { inset: 0; display: block; }
  .dist .dev { position: absolute; block-size: auto; }
  .dist .dev { transform-origin: 50% 100%; }
  .dist .dev--laptop { inset-inline-start: 307.9em; inset-block-start: 450em; }
  .dist .dev--phone { inset-inline-start: 577em; inset-block-start: 414em; inline-size: 92em; transform: scale(0.806); }
  .dist .dev--phone :is(.dev__plug, .dev__dot) { scale: 1.24; }   /* its connector the laptop's size despite the 0.806x */
  /* the laptop's connector sits off its centre, mirroring the phone's about
     the axis, so the bar's arms are equal (owner's pick, 2026-10-01) */
  .dist .dev--laptop :is(.dev__plug, .dev__dot) { inset-inline-start: 37.1em; }
  .shot:is([data-pub], [data-live]) .dist .dist__site { transition: opacity 500ms ease 1000ms; }
  .shot:is([data-pub], [data-live]) .bz-arshot { animation: dist-cross 1500ms ease both; }
  @keyframes dist-cross { 0%, 66% { opacity: 1; } 100% { opacity: 0; } }
}
.dist__frame { position: absolute; inset-block-start: 0; inset-inline-start: 50%; inline-size: 968em; block-size: 605em; margin-inline-start: -484em; }
.dist__frame > * { position: absolute; }
.dist i { font-style: normal; }

/* the dot field over the top of the stage (their canvas) */
.dist__dots {
  inset: 0 0 33% 0;
  background: radial-gradient(circle, rgb(255 255 255 / 0.2) 0.8em, transparent 1.1em) 0 0 / 16em 16em;
  -webkit-mask: radial-gradient(70% 90% at 50% 10%, transparent 20%, #000 45%, transparent 85%); mask: radial-gradient(70% 90% at 50% 10%, transparent 20%, #000 45%, transparent 85%);
  animation: dist-twinkle 4s ease-in-out infinite alternate;
}
@keyframes dist-twinkle { from { opacity: 0.55; } to { opacity: 1; } }

/* the traces: a faint line, a streak (their blue) and its tip (their ice) */
.dist__wires, .dist__circuit { inset: 0; inline-size: 100%; block-size: 100%; overflow: visible; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.dist__w__base { stroke: rgb(255 255 255 / 0.1); stroke-width: 1; }
.dist__circuit .dist__w__base { stroke: rgb(161 187 255 / 0.16); }
.dist__w__tip { stroke-width: 1.4; }
.dist__w__run { stroke: #3076fb; stroke-width: 2.6; stroke-opacity: 0.7; }   /* a wide soft streak for the glow: a drop-shadow filter re-rendered every frame (2026-10-01) */
.dist__w__tip { stroke: #b5ecfe; }
.dist__w__run path { stroke-dasharray: 18 300; stroke-dashoffset: 18; animation: dist-run var(--d) linear var(--o) infinite; }
.dist__w__tip path { stroke-dasharray: 4 300; stroke-dashoffset: 4; animation: dist-tip var(--d) linear var(--o) infinite; }
@keyframes dist-run { 0% { stroke-dashoffset: 18; } 50%, 100% { stroke-dashoffset: -100; } }
@keyframes dist-tip { 0% { stroke-dashoffset: 4; } 50%, 100% { stroke-dashoffset: -114; } }

/* the source: the hero's icon in an 80 box, breathing */
.dist__app {
  inset-inline-start: 444em; inset-block-start: 12em; inline-size: 80em; block-size: 80em; z-index: 2;
  display: grid; place-items: center; box-sizing: border-box; border-radius: 22em; border: 1em solid rgb(255 255 255 / 0.12);
}
.dist__tile {
  position: relative; inline-size: 64em; block-size: 64em; border-radius: 24%;
  background: linear-gradient(180deg, #4f7dff, #1a45e0);
  box-shadow: inset 0 1em 0 rgb(255 255 255 / 0.45), inset 0 0 0 1em rgb(255 255 255 / 0.16), 0 10em 24em -8em rgb(10 30 160 / 0.7);
  animation: dist-breathe 2.25s linear infinite;
}
@keyframes dist-breathe { 0%, 15%, 100% { scale: 1; } 5% { scale: 1.01; } 10% { scale: 0.99; } }
.dist__tile svg { position: absolute; inset: 0; margin: auto; inline-size: 62%; block-size: 62%; fill: none; stroke: #fff; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.dist__tile svg circle { fill: #fff; stroke: none; }
.dist__tile .dist__tile-a { fill: rgb(255 255 255 / 0.5); stroke: none; }

/* the board: three glass layers round the chip */
.dist__board {
  inset-inline-start: 306em; inset-block-start: 140em; inline-size: 356em; block-size: 208em; z-index: 1;
  box-sizing: border-box; border-radius: 30em; border: 1em solid rgb(255 255 255 / 0.12);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.dist__process {
  position: absolute; inset: 7em; border-radius: 22em; background: rgb(161 187 255 / 0.08);
  box-shadow: 0 32em 32em -12em rgb(0 0 44 / 0.16), 0 2em 4em rgb(0 0 44 / 0.07), 0 1em 2em rgb(0 0 44 / 0.12), 0 0.5em 0.5em rgb(0 0 44 / 0.16),
              inset 0 12em 24em rgb(179 179 255 / 0.12), inset 0 1em 1em rgb(179 179 255 / 0.12), inset 0 0.5em 0.5em rgb(179 179 255 / 0.12);
}
.dist__process::before, .dist__inner::before { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1em rgb(161 187 255 / 0.06); pointer-events: none; }
.dist__light {
  position: absolute; inset: 6em; border-radius: 16em;
  box-shadow: 0 2em 4em rgb(179 179 255 / 0.16), 0 1em 2em rgb(179 179 255 / 0.16), 0 0.5em 0.5em rgb(179 179 255 / 0.16),
              inset 0 2em 4em rgb(2 0 43 / 0.16), inset 0 1em 2em rgb(2 0 43 / 0.16), inset 0 0.5em 0.5em rgb(2 0 43 / 0.16);
}
.dist__light::before { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 4em rgb(2 0 41 / 0.32); }
.dist__orbit {
  position: absolute; inset: 0; border-radius: inherit; padding: 4em; overflow: hidden;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude;
}
.dist__orbit::before {
  content: ""; position: absolute; inset-block-start: 50%; left: 50%; translate: -50% -50%; inline-size: 400em; block-size: 400em;
  background: conic-gradient(from -90deg, rgb(17 21 105 / 0), rgb(17 21 105 / 0) 75%, #2a1bd0 90%, #3076fb, #8fa6ff 95%, #b5ecfe);
  animation: dist-turn 6s linear infinite;
}
.dist__glow { position: absolute; inset: -6em; border-radius: 22em; filter: blur(6px); }
@keyframes dist-turn { to { rotate: 1turn; } }
.dist__inner {
  position: absolute; inset: 10em; border-radius: 12em; background: rgb(161 187 255 / 0.04);
  box-shadow: inset 0 12em 32em rgb(179 179 255 / 0.1), inset 0 1em 1em rgb(179 179 255 / 0.12), inset 0 0.5em 0.5em rgb(179 179 255 / 0.12);
}
.dist__chip {
  position: absolute; inset: 0; border-radius: inherit; overflow: hidden;
  background: radial-gradient(circle, rgb(161 187 255 / 0.22) 0.6em, transparent 0.9em) 4em 4em / 9em 9em;   /* their chip's dot canvas */
}
.dist__chip > * { position: absolute; }
.dist__core {
  inline-size: 13em; block-size: 13em; border-radius: 50%; translate: -50% -50%;
  background: linear-gradient(rgb(161 187 255 / 0.06), rgb(161 187 255 / 0)), rgb(161 187 255 / 0.06);
  box-shadow: inset 0 12em 12em rgb(161 187 255 / 0.08), inset 0 12em 24em rgb(161 187 255 / 0.32), inset 0 1em 1em rgb(161 187 255 / 0.32), inset 0 0.5em 0.5em rgb(161 187 255 / 0.32), 0 0 0 1em rgb(161 187 255 / 0.16);
  animation: dist-core 1.5s ease-out infinite;
}
.dist__core--1 { inset-inline-start: 300em; inset-block-start: 30em; animation-delay: -1.1s; }
.dist__core--2 { inset-inline-start: 20em; inset-block-start: 70em; animation-delay: -0.3s; }
.dist__core--3 { inset-inline-start: 300em; inset-block-start: 130em; }
@keyframes dist-core { 0%, 40% { scale: 1; } 20% { scale: 1.05; } }
/* the site, on the chip */
.dist__site {
  inset-inline-start: 40em; inset-block-start: 11em; inline-size: 240em; block-size: 150em; border-radius: 6em;
  overflow: hidden; container-type: inline-size; background: #fff;
  box-shadow: 0 0 0 1em rgb(181 236 254 / 0.3), 0 8em 20em -6em rgb(0 0 30 / 0.6);
}

/* the devices: three 262 slots, 63 apart */
.dist__devs { inset-inline: 0; inset-block-start: 400em; display: flex; justify-content: center; gap: 63em; }
.dev { position: relative; inline-size: 262em; block-size: 186em; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; }
.dev__slot { position: absolute; inset-inline: 0; inset-block-start: -6em; block-size: 124em; box-sizing: border-box; border-radius: 16em; border: 1em solid rgb(255 255 255 / 0.12); }
.dev__plug {
  position: absolute; z-index: 1; inset-inline-start: 50%; inset-block-start: -13em; inline-size: 15em; block-size: 15em; margin-inline-start: -7.5em;
  border-radius: 4em; background: #162099;
  box-shadow: 0 1em 2em rgb(0 4 56 / 0.16), 0 0.5em 0.5em rgb(0 4 56 / 0.16), inset 0 1em 3em rgb(255 255 255 / 0.06), inset 0 0.5em 0.5em rgb(255 255 255 / 0.06), inset 0 0 0 1em rgb(169 157 255 / 0.06);
}
.dev__dot {
  position: absolute; z-index: 2; inset-inline-start: 50%; inset-block-start: -8em; inline-size: 5em; block-size: 5em; margin-inline-start: -2.5em;
  border-radius: 50%; background: rgb(165 153 255 / 0.2);
  box-shadow: inset 0 1em 3em rgb(255 255 255 / 0.06), inset 0 0.5em 0.5em rgb(255 255 255 / 0.06), 0 1em 2em rgb(0 4 56 / 0.06);
}
.dev__stage { position: relative; perspective: 1550em; perspective-origin: 50% 100%; transform-style: preserve-3d; }
.dev__hinge {
  position: relative; margin-inline: auto; transform-origin: 50% 100%; transform-style: preserve-3d;
  transform: rotate3d(-1, 0, 0, 91deg); transition: transform 1s ease;
}
.dev[data-boot] .dev__hinge { transform: rotate3d(-1, 0, 0, 0deg); }
.dev__screen {
  position: relative; box-sizing: border-box; overflow: hidden; background: rgb(42 56 172);
  box-shadow: inset 0 -12em 24em rgb(0 13 102 / 0.32), inset 0 2em 4em rgb(255 255 255 / 0.12), inset 0 1em 2em rgb(255 255 255 / 0.12), inset 0 0.5em 0.5em rgb(255 255 255 / 0.12);
}
.dev__screen::before { content: ""; position: absolute; inset: var(--bz, 3em); border-radius: var(--r, 5em 5em 0 0); background: rgb(11 12 43); }
.dev__screen::after {   /* the glass */
  content: ""; position: absolute; z-index: 3; inset: var(--bz, 3em); border-radius: var(--r, 5em 5em 0 0); pointer-events: none;
  background: linear-gradient(130deg, rgb(160 170 255 / 0) 49.74%, rgb(160 170 255 / 0.078) 49.75%, rgb(1 1 35 / 0) 79.6%);
}
.dev__wall {
  position: absolute; inset: var(--bz, 3em); border-radius: var(--r, 5em 5em 0 0);
  scale: 0.9; filter: blur(8px); opacity: 0; transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
}
.dev[data-boot="done"] .dev__wall { scale: 1; filter: none; opacity: 1; }
/* dark, the screen's own colour, not white (2026-10-05, owner saw white
   screens flash online): if a picture isn't drawn yet the frame it fades
   in, the screen shows dark, as it did while booting. BizArch's page on
   the laptop brings its own white (.bz). */
.dev__page { position: absolute; display: block; overflow: hidden; container-type: inline-size; background: rgb(11 12 43); }
.dev__page, .dev__win { opacity: 0; translate: 0 4em; filter: blur(4px); transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1); }
.dev[data-boot="done"] :is(.dev__page, .dev__win) { opacity: 1; translate: 0 0; filter: none; transition-delay: 400ms; }
.dev__win .dev__page { opacity: 1; translate: none; filter: none; transition: none; }
.dev__boot {
  position: absolute; z-index: 2; inset: var(--boot, 8em); border-radius: 1em; background: #151738;
  display: grid; place-items: center; transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
}
.dev[data-boot="done"] .dev__boot { scale: 1.1; filter: blur(8px); opacity: 0; }
.dev__logo {
  position: relative; display: grid; place-items: center; inline-size: var(--ring, 48em); block-size: var(--ring, 48em); border-radius: 50%;
  background: rgb(1 1 35 / 0.24);
  box-shadow: 0 2em 6em rgb(255 255 255 / 0.04), 0 1em 3em rgb(255 255 255 / 0.06), 0 0.5em 0.5em rgb(255 255 255 / 0.06),
              inset 0 8em 12em rgb(10 10 52 / 0.12), inset 0 2em 4em rgb(10 10 52 / 0.12), inset 0 1em 3em rgb(10 10 52 / 0.12), inset 0 0.5em 0.5em rgb(10 10 52 / 0.12);
}
.dev__logo img { inline-size: 62%; block-size: 62%; border-radius: 22%; }
.dev__logo i {
  position: absolute; inset: 0; border-radius: 50%; padding: 1em; overflow: hidden;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude;
}
.dev__logo i::before {
  content: ""; position: absolute; inset-block-start: 50%; left: 50%; translate: -50% -50%; inline-size: 200em; block-size: 200em;
  background: conic-gradient(from 90deg, rgb(181 236 254 / 0), rgb(17 21 105 / 0) 50%, #2a1bd0 80%, #3076fb, #8fa6ff 90%, #b5ecfe 99.99%, rgb(181 236 254 / 0));
  animation: dist-turn 2s linear infinite;
}

/* the laptop: their lid, hinge strip and keyboard */
.dev--laptop .dev__stage { inline-size: 100%; }
.dev--laptop .dev__hinge { inline-size: 90.84%; }
.dev__strip {
  position: absolute; inset-inline: 0; inset-block-end: 0; margin-inline: auto; display: block; inline-size: 100%; padding: 2.4% 4% 0;
  box-sizing: border-box; transform-origin: 50% 100%; transform: rotateX(90deg); transition: all 1s;
}
.dev[data-boot] .dev__strip { inline-size: 92%; }
.dev__strip i {
  position: absolute; inset: 0 0 auto 0; block-size: 5em; border-radius: 12em 12em 0 0; background: rgb(55 84 220);
  box-shadow: inset 0 -1em 4em rgb(0 13 102 / 0.32), inset 0 2em 4em rgb(255 255 255 / 0.12), inset 0 1em 2em rgb(255 255 255 / 0.12), inset 0 0.5em 0.5em rgb(255 255 255 / 0.12);
}
.dev--laptop .dev__screen { block-size: 140em; padding: 3%; border-radius: 8em 8em 0 0; }
.dev--laptop .dev__wall { background: radial-gradient(90% 120% at 15% 110%, #ff9a52 0%, rgb(255 154 82 / 0) 55%), radial-gradient(80% 90% at 95% 0%, #6b8cff 0%, rgb(107 140 255 / 0) 60%), linear-gradient(165deg, #2338b8 0%, #121a6b 60%, #0b0f45 100%); }
.dev__win {
  position: absolute; z-index: 1; inset-block-start: 14em; inset-inline-start: calc(50% - 84em); inline-size: 168em;
  border-radius: 3.75em; overflow: hidden; background: rgb(5 6 27 / 0.88);
  box-shadow: inset 0 0.156em 0.156em rgb(255 255 255 / 0.06), 0 0.625em 1.25em rgb(0 1 27 / 0.32), 0 0.313em 0.625em rgb(0 1 28 / 0.12), 0 5em 17.5em rgb(0 1 28 / 0.86), 0 0 0 0.5em rgb(255 255 255 / 0.06);
}
.dev__bar { display: flex; align-items: center; gap: 2em; block-size: 9em; padding-inline: 4em; background: linear-gradient(rgb(255 255 255 / 0), rgb(255 255 255 / 0.1)), rgb(5 6 27 / 0.88); }
.dev__bar i { inline-size: 3em; block-size: 3em; border-radius: 50%; background: rgb(255 255 255 / 0.22); }
.dev__bar b { margin-inline: auto; inline-size: 56em; block-size: 5em; border-radius: 2em; background: rgb(255 255 255 / 0.1); font-size: 0; }
.dev__win .dev__page { position: relative; inline-size: 168em; block-size: 105em; }
.dev__keys {
  position: relative; z-index: 1; display: block; inline-size: 262em; block-size: 10em; border-radius: 0 0 16em 16em / 0 0 10em 10em;
  background: linear-gradient(180deg, rgb(86 112 238) 0%, rgb(48 66 190) 55%, rgb(30 42 140) 100%);
  box-shadow: inset 0 1em 0 rgb(255 255 255 / 0.3), 0 8em 14em -6em rgb(0 0 40 / 0.6);
}
.dev__keys::after { content: ""; position: absolute; inset-block-start: 0; inset-inline-start: 50%; inline-size: 40em; block-size: 3.5em; margin-inline-start: -20em; border-radius: 0 0 4em 4em; background: rgb(30 44 150); }

/* the tablet and the phone: no lid, they stand up the same way */
.dev--tablet .dev__stage { inline-size: 250em; }
.dev--tablet .dev__screen { --bz: 6em; --r: 4em; --boot: 6em; block-size: 177em; border-radius: 10em; }   /* screen 238 x 165, the capture's 1180:820 */
.dev--tablet .dev__wall { background: radial-gradient(90% 110% at 100% 100%, #e0569a 0%, rgb(224 86 154 / 0) 60%), radial-gradient(80% 90% at 0% 0%, #7a5cff 0%, rgb(122 92 255 / 0) 60%), linear-gradient(200deg, #3a1f9e 0%, #1a1260 100%); }
.dev--tablet .dev__page { inset: 6em; border-radius: 4em; }
.dev--phone .dev__stage { inline-size: 92em; }
.dev--phone .dev__screen { --bz: 4em; --r: 10em; --boot: 4em; --ring: 40em; block-size: 186em; border-radius: 13em; }
.dev--phone .dev__wall { background: radial-gradient(120% 70% at 50% 110%, #2fb6ff 0%, rgb(47 182 255 / 0) 60%), linear-gradient(180deg, #1b2a9e 0%, #0d1150 100%); }
.dev--phone .dev__page { inset: 4em; border-radius: 10em; }
.dev--phone .dev__boot { border-radius: 10em; }
.dist :is(.bzm, .bzt) { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; object-position: top; }
.dist__site .bzm, .dist .bzd { display: none; }
/* the desktop capture (phones): the whole page, as the live copy on desktop */
.dist .bzd { position: absolute; inset-block-start: 0; inset-inline-end: 0; inline-size: 100%; block-size: auto; max-inline-size: none; }
.dist__wires path:is(:nth-child(5), :nth-child(6)) { display: none; }   /* the phone layout's two traces */

/* BizArch's page, copied in by app.js: shown as it is, at its host's size */
/* whole, on the board and the laptop: the 1.35x close-up cut the dashboard
   off and read like a text-only site (owner, 2026-10-01) */
.shot .dist .bz.bz { opacity: 1; animation: none; transition: none; box-shadow: none; border-radius: 0; z-index: auto; filter: none; clip-path: none; transform: none; }

/* the way in, piece by piece (timeline in "The way in" above). Hidden
   states sit on the pieces; the entrances only on the playing state. */
.dist__dots, .dist__app, .dist__board, .dist__core, .dist__site, .dev, .dist__w__run path, .dist__w__tip path { opacity: 0; }
.dist__app { translate: 0 10em; }
.dist__tile { filter: blur(6px); }
.dist__board { scale: 0.96; }
.dist__w__base path { stroke-dasharray: 100 100; stroke-dashoffset: 100; }
.dist__wires .dist__w__base path:first-child { stroke-dashoffset: -100; }   /* the stem draws up */
.dist__core { filter: blur(3px); }
.dev { translate: 0 8em; }
.shot:is([data-pub], [data-live]) .dist__dots { opacity: 1; transition: opacity 1200ms ease 200ms; }
.shot:is([data-pub], [data-live]) .dist__board { opacity: 1; scale: 1; transition: opacity 800ms ease 300ms, scale 900ms cubic-bezier(0.2, 0.8, 0.2, 1) 300ms; }
.shot:is([data-pub], [data-live]) .dist__site { opacity: 1; transition: opacity 0s 1200ms; }
.shot:is([data-pub], [data-live]) .dist__circuit .dist__w__base path { stroke-dashoffset: 0; transition: stroke-dashoffset 700ms cubic-bezier(0.3, 0.6, 0.3, 1) 1200ms; }
.shot:is([data-pub], [data-live]) .dist__core { opacity: 1; filter: none; transition: opacity 500ms ease 1300ms, filter 500ms ease 1300ms; }
.shot:is([data-pub], [data-live]) .dist__core--2 { transition-delay: 1400ms; }
.shot:is([data-pub], [data-live]) .dist__core--3 { transition-delay: 1500ms; }
.shot:is([data-pub], [data-live]) .dist__circuit :is(.dist__w__run, .dist__w__tip) path { opacity: 1; transition: opacity 400ms 1900ms; }
.shot:is([data-pub], [data-live]) .dist__wires .dist__w__base path { stroke-dashoffset: 0; transition: stroke-dashoffset 800ms cubic-bezier(0.45, 0, 0.25, 1) 2800ms; }
.shot:is([data-pub], [data-live]) .dist__wires .dist__w__base path:first-child { transition: stroke-dashoffset 600ms cubic-bezier(0.45, 0, 0.25, 1) 1600ms; }
.shot:is([data-pub], [data-live]) .dist__wires .dist__w__base path:nth-child(3) { transition-delay: 2860ms; }
.shot:is([data-pub], [data-live]) .dist__wires .dist__w__base path:nth-child(4) { transition-delay: 2920ms; }
.shot:is([data-pub], [data-live]) .dist__app { opacity: 1; translate: 0 0; transition: opacity 700ms ease 2000ms, translate 800ms cubic-bezier(0.2, 0.8, 0.2, 1) 2000ms; }
.shot:is([data-pub], [data-live]) .dist__tile { filter: none; transition: filter 700ms ease 2050ms; }
.shot:is([data-pub], [data-live]) .dist__wires :is(.dist__w__run, .dist__w__tip) path { opacity: 1; transition: opacity 400ms 3700ms; }
.shot:is([data-pub], [data-live]) .dist__wires :is(.dist__w__run, .dist__w__tip) path:first-child { transition-delay: 2700ms; }
.shot:is([data-pub], [data-live]) .dev { opacity: 1; translate: 0 0; transition: opacity 600ms ease 3300ms, translate 700ms cubic-bezier(0.2, 0.8, 0.2, 1) 3300ms; }
.shot:is([data-pub], [data-live]) .dev--laptop { transition-delay: 3360ms; }
.shot:is([data-pub], [data-live]) .dev--tablet { transition-delay: 3420ms; }

/* At rest (owner, 2026-10-01): ToDesktop's loops run ~20s before their film
   moves on; ours rests here for good, so 8s after the end app.js halves
   the lights' speed (Web Animations playbackRate, no jump) and sets
   data-calm, which dims them, so they stop pulling the eye from the way
   down. Performance: once live, the panel's own glass blur is dropped (it
   is transparent by then); on phones the orbit's blurred copy and the dot
   twinkle are left out (a blur re-rendered every frame). Measured at rest
   on a laptop: 60fps, no long tasks. */
.dist__w__run, .dist__w__tip, .dist__orbit { transition: opacity 1500ms ease; }
.shot[data-calm] .dist :is(.dist__w__run, .dist__w__tip) { opacity: 0.55; }
.shot[data-calm] .dist__orbit { opacity: 0.6; }
.shot[data-live] { -webkit-backdrop-filter: none; backdrop-filter: none; }
@media (max-width: 40rem) {
  .dist__glow { display: none; }
  .dist__dots { animation: none; }
}

/* the lights run only while the ending plays and the panel is on screen */
.dist *, .dist *::before { animation-play-state: paused; }
.shot:is([data-pub], [data-live]):not([data-idle]) :is(.dist, .dist *), .shot:is([data-pub], [data-live]):not([data-idle]) .dist *::before { animation-play-state: running; }
@media (prefers-reduced-motion: reduce) {
  .dist, .dist *, .dist *::before, .shot, .shot__bar > *, .shot__view { animation: none !important; transition: none !important; }
}

/* back to top (2026-10-02, owner): a plain text link in the footer's bottom
   row, after Privacy, as most reference sites do (a floating arrow was tried
   the same day and dropped: it read as a template add-on beside WhatsApp).
   Phones: room under the footer so the last line clears the WhatsApp button
   (16 + 52px from the bottom) when the page ends. */
.tf__top { white-space: nowrap; }
@media (max-width: 40rem) { .tf__in { padding-block-end: 96px; } }

/* ══ The language switch (2026-10-04, owner) ═══════════════════════════════
   Apple's Control Center tile (the Focus pill), chosen in lab/lang-switch.html,
   glass: a circle with the language you are in (EN / ع), then the other one
   in its own script (عربي / English). It is a link to the other page, kept on
   the same section (app.js, the language switch). Where it lives: the hero's
   nav and the footer; not the floating pill (owner: like the theme switch,
   it doesn't ride along); on phones it takes "Let's talk"'s place in the
   hero nav (the nav only exists on the hero there, and the hero's own
   "Send your website" sits right below). Undo = delete this block and the
   .lsw links in index.html and ar.html. */
.lsw {
  display: inline-flex; align-items: center; gap: 8px; flex: none;
  block-size: 40px; padding-block: 4px; padding-inline: 4px 14px;
  border-radius: 999px; text-decoration: none; white-space: nowrap; letter-spacing: 0;
  color: var(--color-ink);
  background: linear-gradient(180deg, rgb(255 255 255 / 0.85), rgb(255 255 255 / 0.55));
  -webkit-backdrop-filter: blur(14px) saturate(1.4); backdrop-filter: blur(14px) saturate(1.4);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.9), inset 0 0 0 1px rgb(0 0 0 / 0.06), 0 4px 14px -4px rgb(0 0 0 / 0.14);
  transition: box-shadow 200ms var(--ease-out);
}
.lsw[hidden] { display: none; }
.lsw__c {
  flex: none; display: grid; place-items: center; inline-size: 32px; block-size: 32px; border-radius: 50%;
  background: linear-gradient(180deg, #fff, #f0f0f0); color: var(--color-ink);
  box-shadow: inset 0 1px 0 #fff, 0 1px 3px rgb(0 0 0 / 0.12);
  transition: color 200ms var(--ease-out);
  position: relative; isolation: isolate;
}
/* the hover blue is a layer that fades (owner, 2026-10-05): the chip's
   resting fill is a gradient, and a gradient can't ease into a colour, so
   swapping the background snapped the blue on and off */
.lsw__c::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  background: var(--color-accent); opacity: 0; transition: opacity 200ms var(--ease-out);
}
.lsw:hover .lsw__c::before { opacity: 1; }
.lsw__c[lang="en"] { font: 600 11.5px/1 "Inter", sans-serif; letter-spacing: 0.04em; }
.lsw__c[lang="ar"] { font: 600 15px/1 "Noto Kufi Arabic", "Noto Sans Arabic", sans-serif; padding-block-end: 2px; }
.lsw__t[lang="ar"] { font: 500 15px/1 "Noto Sans Arabic", sans-serif; padding-block-end: 1px; }
.lsw__t[lang="en"] { font: 500 14px/1 "Inter", sans-serif; }
.lsw:hover .lsw__c { color: #fff; }
.lsw:focus-visible { outline: var(--rule-bold) solid var(--color-focus); outline-offset: 2px; }
/* on the hero's night sky */
.nav[data-tone="dark"] .lsw {
  color: rgb(255 255 255 / 0.92);
  background: linear-gradient(180deg, rgb(255 255 255 / 0.16), rgb(255 255 255 / 0.06));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.28), inset 0 0 0 1px rgb(255 255 255 / 0.12), 0 6px 18px -6px rgb(0 0 0 / 0.45);
}
.nav[data-tone="dark"] .lsw__c { background: linear-gradient(180deg, rgb(255 255 255 / 0.32), rgb(255 255 255 / 0.16)); color: #fff; box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.35); }
/* the dark theme, off the sky (the footer) */
[data-theme="dark"] .tf .lsw {
  color: var(--color-ink);
  background: linear-gradient(180deg, rgb(255 255 255 / 0.10), rgb(255 255 255 / 0.04));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.16), inset 0 0 0 1px rgb(255 255 255 / 0.08), 0 4px 14px -4px rgb(0 0 0 / 0.4);
}
[data-theme="dark"] .tf .lsw__c { background: linear-gradient(180deg, rgb(255 255 255 / 0.22), rgb(255 255 255 / 0.10)); color: #fff; box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.25); }
.lsw:hover .lsw__c { color: #fff; }
/* not in the floating pill */
.nav[data-tone="light"] .lsw { display: none; }
/* pressed, on touch (app.js, 2026-10-06): drawn at the touch, before Safari
   stops drawing this page for the switch, and held still: the circle fills
   blue at once (no 200ms fade), the word dims, the pill sinks a touch */
.lsw.is-pressed { transform: scale(0.96); }
.lsw.is-pressed .lsw__c::before { opacity: 1; transition: none; }
.lsw.is-pressed .lsw__c { color: #fff; transition: none; }
.lsw.is-pressed .lsw__t { opacity: 0.6; }
@media (max-width: 40rem) {
  .nav__end:has(.lsw:not([hidden])) .nav__cta { display: none; }
}

/* ══ The more menu (2026-10-04, owner) ═════════════════════════════════════
   Three controls on the hero's right was one too many: the theme moved
   behind a ⋮ (after Chrome's and Claude's), at the very end, after "Let's
   talk" (owner: in the middle it looked off). At rest only the three dots; a round glass circle behind
   them on hover and while open (round, like everything else in the bar).
   The menu is a small card under it, flush with its outer edge: a heading,
   then Light and Dark with a tick on the current one (app.js, the theme
   toggle). The hero is night in both themes, so the card is white glass in
   light and dark glass in dark. Hero only, phones too (it sits beside the
   language switch); the floating pill carries none, the footer keeps its
   switch. Undo = delete this block and the .kebab in index.html and
   ar.html, and put the .tseg--nav back. */
.kebab { position: relative; flex: none; }
.kebab__btn {
  display: grid; place-items: center; inline-size: 40px; block-size: 40px; padding: 0;
  border: 0; border-radius: 50%; background: transparent; cursor: pointer;
  color: rgb(255 255 255 / 0.78);
  transition: background-color 200ms var(--ease-out), color 200ms var(--ease-out), box-shadow 200ms var(--ease-out);
}
.kebab__btn svg { inline-size: 20px; block-size: 20px; fill: currentColor; }
.kebab__btn:hover, .kebab[data-open] .kebab__btn {
  color: #fff;
  background: linear-gradient(180deg, rgb(255 255 255 / 0.16), rgb(255 255 255 / 0.06));
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.28), inset 0 0 0 1px rgb(255 255 255 / 0.12);
}
.kebab__btn:focus-visible { outline: var(--rule-bold) solid #fff; outline-offset: 2px; }
.kebab__menu {
  position: absolute; z-index: 30; inset-block-start: calc(100% + 10px); inset-inline-end: 0;
  min-inline-size: 184px; padding: 6px; border-radius: 16px;
  color: #141414;
  background: rgb(255 255 255 / 0.95);
  -webkit-backdrop-filter: blur(20px) saturate(1.6); backdrop-filter: blur(20px) saturate(1.6);
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / 0.06), 0 12px 32px -8px rgb(0 0 0 / 0.35), 0 2px 8px rgb(0 0 0 / 0.12);
  transform-origin: top right;
  opacity: 0; visibility: hidden; scale: 0.96; translate: 0 -4px;
  transition: opacity 140ms var(--ease-out), scale 160ms var(--ease-out), translate 160ms var(--ease-out), visibility 0s 160ms;
}
[dir="rtl"] .kebab__menu { transform-origin: top left; }
.kebab[data-open] .kebab__menu {
  opacity: 1; visibility: visible; scale: 1; translate: 0 0;
  transition: opacity 160ms var(--ease-out), scale 200ms var(--ease-out), translate 200ms var(--ease-out), visibility 0s;
}
.kebab__h {
  margin: 0; padding: 6px 10px 4px;
  font: 500 12px/16px var(--font-body); letter-spacing: 0; color: rgb(20 20 20 / 0.5);
}
.kebab__item {
  display: grid; grid-template-columns: 18px 1fr 16px; align-items: center; gap: 10px;
  inline-size: 100%; min-block-size: 38px; padding: 0 10px; border: 0; border-radius: 10px;
  background: none; color: inherit; cursor: pointer; text-align: start;
  font: 500 14px/20px var(--font-body); letter-spacing: 0;
}
.kebab__item svg { inline-size: 18px; block-size: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.kebab__item .kebab__tick { inline-size: 16px; block-size: 16px; stroke-width: 2; color: var(--color-accent); opacity: 0; }
.kebab__item[aria-checked="true"] .kebab__tick { opacity: 1; }
.kebab__item:hover, .kebab__item:focus-visible { background: rgb(0 0 0 / 0.06); outline: none; }
.kebab__item:focus-visible { box-shadow: inset 0 0 0 2px var(--color-focus); }
[data-theme="dark"] .kebab__menu {
  color: #fff; background: rgb(28 24 40 / 0.86);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.1), inset 0 1px 0 rgb(255 255 255 / 0.08), 0 12px 32px -8px rgb(0 0 0 / 0.6), 0 2px 8px rgb(0 0 0 / 0.3);
}
[data-theme="dark"] .kebab__h { color: rgb(255 255 255 / 0.5); }
[data-theme="dark"] .kebab__item:hover, [data-theme="dark"] .kebab__item:focus-visible { background: rgb(255 255 255 / 0.08); }
[data-theme="dark"] .kebab__item .kebab__tick { color: oklch(72% 0.15 268); }
@media (prefers-reduced-motion: reduce) { .kebab__menu, .kebab[data-open] .kebab__menu { transition: none; } }
/* not in the floating pill */
.nav[data-tone="light"] .kebab { display: none; }
