/* Riwaq Labs. Ink on paper: the page is a request form. Two colours at rest, vermilion only while a stamp is wet. */

:root {
  color-scheme: light;
  --paper: oklch(0.9643 0.0070 88.64);              /* #F5F3EE */
  --ink: oklch(0.1829 0.0382 260.22);               /* #081223, sampled from the wordmark */
  --stamp: oklch(0.5491 0.1901 31.82);              /* #C8321A, 4.8:1 on paper */
  --rule: oklch(0.1829 0.0382 260.22 / 0.18);
  --ink-2: color-mix(in srgb, var(--ink) 76%, var(--paper));    /* secondary text, a tint of Ink, about 8.3:1 */
  --wash: color-mix(in oklch, var(--ink) 4%, var(--paper));
  --grain: url("assets/brand/grain.png");
  --sans: "Schibsted Grotesk", "Helvetica Neue", Arial, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace;
  --display: clamp(2.5rem, 6vw, 5.5rem);
  --header-h: 64px;
  --strip-h: 0px;
  --gutter: 16px;
  --step: 0px;
}
@media (min-width: 768px) { :root { --gutter: 32px; --step: 26px; } }
@media (min-width: 1200px) { :root { --gutter: 48px; } }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* The offset sits on the targets, not the scroller, so focus on the sticky masthead never scrolls the page. */
main, main [id], main a, main button, main input, footer a { scroll-margin-top: calc(var(--header-h) + var(--strip-h) + 16px); }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body {
  margin: 0;
  background: var(--paper) var(--grain);
  color: var(--ink);
  font: 400 1.0625rem/1.55 var(--sans);
  overflow-x: clip;
}
img, video, svg { display: block; max-width: 100%; height: auto; }
h1, h2, h3, p, ul, ol, dl, dd, figure, fieldset { margin: 0; padding: 0; }
ul, ol { list-style: none; }
[hidden] { display: none !important; }

a, button, label, summary, select, input[type="checkbox"] { cursor: pointer; }
button:disabled, [aria-disabled="true"] { cursor: not-allowed; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
main:focus { outline: none; }
a:hover { text-decoration-thickness: 2px; }
a:active, .opt:active { opacity: .7; }
.masthead-mark:hover img { opacity: .8; }
h2[tabindex="-1"]:focus { outline: none; }
h2[tabindex="-1"]:focus-visible { outline: 2px solid var(--ink); outline-offset: 6px; }

.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: var(--gutter); top: 8px; z-index: 100;
  min-height: 44px; display: inline-flex; align-items: center;
  transform: translateY(-200%);
  background: var(--ink); color: var(--paper); padding: 10px 16px;
  font: 500 0.875rem var(--mono); text-decoration: none;
}
.skip:focus { transform: none; }

/* ---------- Controls ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 0 22px;
  background: var(--ink); color: var(--paper);
  border: 1px solid var(--ink); border-radius: 2px;
  font: 600 1rem/1 var(--sans); text-decoration: none;
  transition: background-color .15s, color .15s;
}
.btn:hover { background: var(--paper); color: var(--ink); }
.btn:active { transform: translateY(1px); }
.btn-quiet { background: transparent; color: var(--ink); min-height: 44px; padding: 0 16px; font-size: .9375rem; }
.btn-quiet:hover { background: var(--ink); color: var(--paper); }
.btn[aria-disabled="true"], .btn[aria-disabled="true"]:hover { background: transparent; color: var(--ink); border-style: dashed; transform: none; }
.text-link {
  display: inline-flex; align-items: center; min-height: 44px;
  font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px;
}
.text-link:hover { text-decoration-thickness: 2px; }
.text-link:active { opacity: .7; }

/* Registration marks: crop ticks outside each corner of a ruled frame */
.reg { position: relative; }
.reg::after {
  content: ""; position: absolute; inset: -9px; pointer-events: none; z-index: 3;
  background:
    linear-gradient(var(--ink), var(--ink)) top left / 12px 1px no-repeat,
    linear-gradient(var(--ink), var(--ink)) top left / 1px 12px no-repeat,
    linear-gradient(var(--ink), var(--ink)) top right / 12px 1px no-repeat,
    linear-gradient(var(--ink), var(--ink)) top right / 1px 12px no-repeat,
    linear-gradient(var(--ink), var(--ink)) bottom left / 12px 1px no-repeat,
    linear-gradient(var(--ink), var(--ink)) bottom left / 1px 12px no-repeat,
    linear-gradient(var(--ink), var(--ink)) bottom right / 12px 1px no-repeat,
    linear-gradient(var(--ink), var(--ink)) bottom right / 1px 12px no-repeat;
}

/* Field box: a ruled box with a mono label set into its top rule */
.field-box { border: 1px solid var(--ink); padding: 22px 20px 20px; position: relative; }
.field-box-label {
  position: absolute; top: 0; left: 14px; transform: translateY(-50%);
  padding: 0 6px; background: var(--paper) var(--grain);
  font: 500 .8125rem/1 var(--mono);
}
fieldset.field-box { min-width: 0; }
legend.field-box-label { position: static; transform: none; float: none; margin-left: -6px; padding: 0 6px; }
fieldset.field-box > legend + * { margin-top: 8px; }

/* ---------- Masthead ---------- */
.masthead {
  position: sticky; top: 0; z-index: 40;
  height: var(--header-h);
  display: flex; align-items: center;
  padding: 0 var(--gutter);
  background: var(--paper) var(--grain);
  border-bottom: 1px solid var(--rule);
}
.masthead-mark { display: inline-flex; align-items: center; min-height: 44px; }
.masthead-mark img { width: auto; height: 30px; mix-blend-mode: multiply; }

/* ---------- Page column ---------- */
main > section, .footer-inner {
  width: min(100% - 2 * var(--gutter), 1360px);
  margin-inline: auto;
}

/* ---------- Opening ---------- */
.opening { padding: clamp(40px, 7vh, 88px) 0 clamp(64px, 10vh, 120px); }
.opening-grid { display: grid; gap: 56px; }
h1 {
  font-size: var(--display); line-height: 1.02; font-weight: 700; letter-spacing: -0.025em;
  max-width: 17ch; text-wrap: balance;
}
.lede { margin-top: 28px; font-size: clamp(1.125rem, 1.6vw, 1.375rem); line-height: 1.45; max-width: 36rem; }
.actions { margin-top: 32px; display: flex; flex-wrap: wrap; align-items: center; gap: 12px 28px; }
/* The clients line on the first screen: the same ruled field box as the Clients box further down. */
.opening-clients { margin-top: 36px; max-width: 36rem; }
.opening-clients > p:not(.field-box-label) { font-size: 1.0625rem; line-height: 1.45; }
.opening-clients .confidential { margin-top: 10px; font-weight: 600; }
@media (min-width: 1280px) {
  .opening-grid { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: 32px; align-items: start; }
  /* The copy scrolls with the page; only the request beside it is pinned while it opens and closes. */
  .opening-copy { grid-column: 1 / 6; }
  .stack { grid-column: 6 / 13; margin-right: calc(16px - var(--gutter)); }
  h1 { font-size: clamp(2.75rem, 3.7vw, 5.5rem); max-width: none; }
}

/* The exploded drawing (HTML fallback for the Three.js stack) */
.stack { position: relative; }
.stack3d-mount:empty { display: none; }
.drawing { display: grid; gap: 16px; }
.layer { position: relative; }
.layer-label { font: 500 .75rem/1 var(--mono); display: inline-block; margin-bottom: 6px; }
.plane {
  position: relative; background: var(--paper) var(--grain);
  border: 1px solid var(--ink); padding: 14px 16px;
}
.plane-screen { padding: 0; overflow: hidden; }
.plane-screen img { width: 100%; }
@media (min-width: 768px) {
  .layer { padding-left: calc(6rem + var(--i) * var(--step)); }
  .layer-label {
    position: absolute; left: 0; top: 50%; margin: 0; transform: translateY(-50%);
    width: calc(6rem + var(--i) * var(--step)); display: flex; align-items: center; gap: 8px;
  }
  .layer-label::after { content: ""; flex: 1; border-top: 1px solid var(--ink); }
  .layer-screen .layer-label { top: 32px; }
  /* Offset outlines: diagonals join each plane's corners to the plane above it */
  .layer + .layer .plane::before, .layer + .layer .plane::after {
    content: ""; position: absolute; top: -17px; width: var(--step); height: 16px;
    background: linear-gradient(to top right, transparent calc(50% - .6px), var(--ink) 50%, transparent calc(50% + .6px));
  }
  .layer + .layer .plane::before { left: calc(-1 * var(--step) - 1px); }
  .layer + .layer .plane::after { left: calc(100% - 1px); width: 1px; background: var(--ink); }
}
.route-steps { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 0; font: 500 .875rem/1.2 var(--mono); }
.route-steps li { display: flex; align-items: center; gap: 8px; }
.route-steps li + li::before { content: ""; width: clamp(16px, 4vw, 40px); border-top: 1px solid var(--ink); margin: 0 10px; }
.route-steps i { width: 14px; height: 14px; border: 1.5px solid var(--ink); position: relative; flex: none; }
.route-steps [data-step="done"] i { background: var(--ink); }
.route-steps [data-step="current"] i::after { content: ""; position: absolute; inset: 3px; background: var(--ink); }
.route-steps [data-step="current"] { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 5px; }
[data-next-action] { font-size: 1.125rem; font-weight: 600; }
.history { font: 400 .8125rem/1.6 var(--mono); }
.ink-in { animation: ink-in .4s ease-out both; }
@keyframes ink-in { from { opacity: 0; } to { opacity: 1; } }

.plane-stamp {
  position: absolute; left: 50%; top: 50%; z-index: 2;
  translate: -50% -50%;
  padding: 8px 18px; border: 3px solid currentColor; color: var(--ink);
  background: oklch(0.9643 0.0070 88.64 / 0.86);
  font: 700 clamp(1.5rem, 3.4vw, 2.75rem)/1.1 var(--sans); white-space: nowrap;
  opacity: 0; pointer-events: none;
}
.drawing[data-state="approved"] .plane-stamp { opacity: 1; }
.stack-label { margin-top: 18px; font: 400 .8125rem/1.5 var(--mono); max-width: 40rem; }
.approve-row { margin-top: 20px; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; }
.approve-note { font: 400 .8125rem/1.5 var(--mono); color: var(--ink-2); }
/* The Three.js stack (stack3d.js): wide, fine-pointer screens with motion allowed. The drawing stays in
   layout and in the accessibility tree; the canvas only paints over it.
   pre-3d is set by main.js at first paint when the 3D stack will run and kept for the whole visit, so the page
   height never changes when the 3D mounts, hands over or fails: a taller Opening with the stack pinned. */
@media (min-width: 1280px) {
  .pre-3d .opening { height: 230vh; padding-bottom: 0; }
  .pre-3d .opening-grid { height: 100%; grid-template-rows: auto 1fr; align-items: start; }
  .pre-3d .stack { position: sticky; top: calc(var(--header-h) + 24px); z-index: 30; }
}
/* Between first paint and main.js measuring the hidden layers (--rest-h), the stack is not shown, so the card never
   appears in a wrong place first. The Opening already has its final height. */
.pre-3d:not(.pre-3d-ready) .stack { visibility: hidden; }
.has-3d .drawing { opacity: 0; pointer-events: none; }
.stack3d-mount { position: fixed; inset: 0; z-index: 1; pointer-events: none; }
.stack3d-canvas, .stack3d-labels { position: absolute; inset: 0; width: 100%; height: 100%; }
.stack3d-labels { overflow: visible; }
.stack3d-labels line { stroke: var(--ink); stroke-width: 1; }
.stack3d-labels text { font: 500 12px var(--mono); fill: var(--ink); dominant-baseline: middle; }
#approve.is-3d { position: relative; z-index: 5; will-change: transform; }
#approve.is-3d[aria-disabled="true"] { background: var(--paper); }
/* The row's transform makes it its own layer, under the canvas; while the button rides on the drawn Approve
   (stack3d.js sets is-riding) the row rises above the canvas, so its hover, focus ring and "Approved" show. */
.pre-3d .approve-row.is-riding, .pre-3d .approve-row:has(:focus-visible) { position: relative; z-index: 2; }
/* Once approved, the instruction to press Approve goes; visibility keeps its box, so nothing moves. */
.drawing[data-state="approved"] ~ .approve-row .approve-note { visibility: hidden; }
/* At rest the 3D stack is one closed card (pre-3d shows it that way from first paint): the caption and the Approve
   row sit right under it and move down with its bottom edge as it opens. stack3d.js writes --open from 0 to 1 and
   main.js --rest-h, the height of the hidden layers. They move by transform, so nothing reflows while scrolling. */
.pre-3d .drawing .layer:not(.layer-screen) { opacity: 0; }
.pre-3d .layer-screen .layer-label { opacity: 0; }
@media (min-width: 768px) { .pre-3d .stack-label, .pre-3d .approve-row { margin-left: 6rem; } }
.pre-3d .drawing { margin-bottom: calc(40px - var(--rest-h, 0px)); }
.pre-3d .stack-label, .pre-3d .approve-row { transform: translateY(calc(var(--open, 0) * (var(--rest-h, 0px) - 40px))); }
@media (min-width: 1280px) { .pre-3d .opening-grid { grid-template-rows: auto; } }
/* While pinned, the whole stack (planes, caption, note) fits one screen: the screen plane is sized from the height. */
.pre-3d .stack { width: min(100%, calc((100vh - var(--header-h) - 430px) * 16 / 9 + 6rem)); }
@media (max-width: 1279px) { .pre-3d .stack { margin-inline: auto; } }
/* Without the 3D stack, the drawing's three planes slide out from under the capture once it is in view (main.js). */
.drawing .layer:not(.layer-screen) .plane {
  transition: transform .9s cubic-bezier(.16, 1, .3, 1) calc(var(--i) * 80ms), opacity .9s ease-out calc(var(--i) * 80ms);
}
.drawing.planes-closed .layer:not(.layer-screen) .plane { transform: translateY(calc(var(--i) * -56px)); opacity: 0; }

@media (max-width: 767px) {
  .stack { margin-top: -16px; }
  .route-steps { flex-direction: column; align-items: flex-start; gap: 10px; }
  .route-steps li + li::before { display: none; }
}

/* ---------- Products and clients ----------
   Logos side by side, each painted in ink from a monochrome mask (assets/logos), with one line under it. As the row
   comes into view each logo assembles the way the Rayyeh app's splash does: the symbol travels in from the logo's
   centre and settles while the rest of the wordmark is uncovered from the left. Per logo (from logos.json): --ar is
   width over height, --split the symbol's right edge and --sym-x its centre, both as fractions of the width. */
.trusted { padding-top: clamp(96px, 14vh, 160px); }
.trusted-h { font: 500 .875rem/1.5 var(--mono); color: var(--ink-2); text-align: center; text-wrap: balance; }
.logo-row {
  margin-top: 32px; padding-top: 40px; border-top: 1px solid var(--ink);
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 48px 32px;
}
@media (max-width: 899px) { .logo-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.logo-item { display: grid; grid-template-columns: minmax(0, 1fr); justify-items: center; align-content: start; text-align: center; }
.logo-item:nth-child(2) { --d: .12s; }
.logo-item:nth-child(3) { --d: .24s; }
.logo-item:nth-child(4) { --d: .36s; }
/* The link fills its column and clips sideways, so neither a wide logo nor the large waiting symbol widens the page
   on a phone; --h is the logo's height where the column has room, and a narrower column scales the logo down. */
.logo-link { justify-self: stretch; display: flex; justify-content: center; align-items: center; min-height: 68px; padding: 6px 8px; overflow-x: clip; }
.logo-art { position: relative; display: block; flex: none; width: calc(var(--h, 44px) * var(--ar, 3)); max-width: 100%; aspect-ratio: var(--ar, 3); }
.logo-part {
  position: absolute; inset: 0; background: var(--ink);
  -webkit-mask: var(--logo) center / 100% 100% no-repeat; mask: var(--logo) center / 100% 100% no-repeat;
}
.logo-letters { clip-path: inset(-2px -2px -2px calc(var(--split, 0) * 100%)); }
.logo-symbol { clip-path: inset(-2px calc((1 - var(--split, 0)) * 100%) -2px -2px); transform-origin: calc(var(--sym-x, .5) * 100%) 50%; }
.logo-kind { margin-top: 14px; font: 500 .75rem/1.3 var(--mono); letter-spacing: .06em; text-transform: uppercase; }
.logo-desc { margin-top: 6px; font-size: .9375rem; line-height: 1.45; max-width: 26ch; color: var(--ink-2); }
/* Waiting: the symbol sits large at the logo's centre and the wordmark is covered. In: one assembly per logo, on
   the Rayyeh splash's own timing (SplashView.swift, RayyehMotion.swift): after 160 ms the symbol travels for 820 ms
   (ease in and out) from 2.05x at the centre to a 2 px, 1.5% short pose, then a soft spring settles it exactly;
   560 ms into the travel the wordmark uncovers from the left over 660 ms (ease in and out). */
.logo-row.is-waiting:not(.is-in) .logo-symbol { transform: translateX(calc((.5 - var(--sym-x, .5)) * 100%)) scale(var(--sym-s0, 2.05)); }
.logo-row.is-waiting:not(.is-in) .logo-letters { clip-path: inset(-2px 100% -2px calc(var(--split, 0) * 100%)); }
.logo-row.is-waiting.is-in .logo-symbol { animation: logo-symbol 1.18s linear calc(var(--d, 0s) + .16s) both; }
/* A wordmark with no separate symbol (RIWAQ) starts uncovering at once instead of waiting for a symbol to travel. */
.logo-row.is-waiting.is-in .logo-letters { animation: logo-letters .66s cubic-bezier(.42, 0, .58, 1) calc(var(--d, 0s) + var(--letters-at, .72s)) both; }
@keyframes logo-symbol {
  0% { transform: translateX(calc((.5 - var(--sym-x, .5)) * 100%)) scale(var(--sym-s0, 2.05)); animation-timing-function: cubic-bezier(.42, 0, .58, 1); }
  69.5% { transform: translateX(-2px) scale(.985); animation-timing-function: cubic-bezier(.3, 1.25, .5, 1); }
  100% { transform: none; }
}
@keyframes logo-letters {
  from { clip-path: inset(-2px 100% -2px calc(var(--split, 0) * 100%)); }
  to { clip-path: inset(-2px -2px -2px calc(var(--split, 0) * 100%)); }
}

/* The visitor's own request: "Sent" stamps like the other stamps once they book or write. */
[data-you-status] { display: inline-block; transform-origin: left center; }
[data-you-status].is-stamped { font-weight: 700; }

/* ---------- What we build ---------- */
.build, .how, .founders, .contact { padding-top: clamp(96px, 14vh, 160px); }
.section-h { font-size: clamp(2.25rem, 4.6vw, 4.25rem); line-height: 1; font-weight: 700; letter-spacing: -0.03em; margin-bottom: 40px; }
.request-type { padding: 26px 20px 8px; }
.build-lead { font-size: clamp(1.125rem, 1.5vw, 1.3125rem); max-width: 40rem; margin-bottom: 14px; }
.options li { border-top: 1px solid var(--rule); padding: 14px 0; }
html:not(.js) .options li { padding-left: 0; }
.opt { display: grid; grid-template-columns: 24px 1fr; gap: 16px; align-items: start; margin: -14px 0; padding: 14px 8px; min-height: 44px; }
.opt:hover { background: var(--wash); }
.opt input {
  appearance: none; -webkit-appearance: none; margin: 2px 0 0; width: 22px; height: 22px;
  border: 1.5px solid var(--ink); border-radius: 0; background: var(--paper);
  display: grid; place-content: center;
}
.opt input::before { content: ""; width: 12px; height: 7px; border: solid var(--paper); border-width: 0 0 2.5px 2.5px; rotate: -45deg; translate: 0 -2px; }
.opt input:checked { background: var(--ink); }
.opt input:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.build-note { margin-top: 20px; font: 400 .875rem/1.5 var(--mono); }

/* ---------- How we work ---------- */
.route-slip { border: 1px solid var(--ink); }
.route-slip-head { font: 500 .8125rem/1 var(--mono); padding: 14px 18px; border-bottom: 1px solid var(--ink); }
.how-lead { padding: 18px 18px 6px; font-size: clamp(1.125rem, 1.5vw, 1.3125rem); }
.route-row {
  display: grid; gap: 6px 24px; padding: 18px; border-top: 1px solid var(--rule);
  grid-template-columns: 1fr auto; grid-template-areas: "step status" "fromto fromto" "copy copy";
}
.route-step { grid-area: step; font-size: 1.1875rem; font-weight: 600; }
.route-fromto { grid-area: fromto; font: 400 .8125rem/1.4 var(--mono); }
.route-copy { grid-area: copy; }
.route-status { grid-area: status; align-self: start; font: 500 .75rem/1 var(--mono); border: 1px solid var(--ink); padding: 6px 8px; white-space: nowrap; }
.route-row:first-child .route-status { background: var(--ink); color: var(--paper); }
@media (min-width: 900px) {
  .route-row { grid-template-columns: 13rem 11rem 1fr 9rem; grid-template-areas: "step fromto copy status"; align-items: baseline; }
  .route-status { justify-self: end; }
}
.hours { margin-top: 44px; max-width: 46rem; }
.clocks { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 8px 28px; font: 500 .9375rem var(--mono); }
.clocks time { font-weight: 500; }

/* ---------- Founders: the signature block ---------- */
.founders-line { font-size: clamp(1.125rem, 1.5vw, 1.3125rem); max-width: 40rem; margin-top: -16px; }
.signatures { margin-top: 48px; display: grid; gap: 56px; }
@media (min-width: 768px) { .signatures { grid-template-columns: repeat(2, minmax(0, 360px)); column-gap: clamp(48px, 8vw, 120px); } }
.portrait { border: 1px solid var(--ink); max-width: 360px; }
.portrait img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.signer figcaption { margin-top: 56px; }
.sig-line { border-top: 1px solid var(--ink); padding-top: 8px; font: 500 .8125rem/1.5 var(--mono); }

/* ---------- Contact ---------- */
.contact { padding-bottom: clamp(80px, 12vh, 140px); }
.contact-field { font: 500 .8125rem/1.5 var(--mono); padding-bottom: 10px; border-bottom: 1px solid var(--ink); }
.contact h2 { margin-top: 32px; font-size: var(--display); line-height: 1; font-weight: 700; letter-spacing: -0.03em; }
.contact-line { margin-top: 24px; font-size: clamp(1.125rem, 1.5vw, 1.3125rem); max-width: 40rem; }
/* The live time is its own line, so "It is" never wraps away from the time. */
.contact-line [data-contact-time] { display: block; }
.contact-confidential { margin-top: 32px; max-width: 40rem; }
.contact-confidential > p:last-child { font-size: clamp(1.125rem, 1.5vw, 1.3125rem); font-weight: 600; }
.contact-actions { margin-top: 32px; display: flex; flex-wrap: wrap; align-items: center; gap: 16px 28px; }
.email-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.email-address { font: 600 1.25rem var(--sans); text-underline-offset: 5px; min-height: 44px; display: inline-flex; align-items: center; }
.pending-note { margin-top: 32px; padding: 16px 18px; border: 1px dashed var(--ink); max-width: 40rem; }

/* ---------- Footer: the bottom of the request ---------- */
.footer { padding: 0 0 40px; }
/* One block under one rule: the wordmark and Book a call on the top line, then the links. */
.footer-inner { display: grid; gap: 20px; border-top: 2px solid var(--ink); padding-top: 48px; }
.footer-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px 32px; }
.footer-mark { width: 140px; height: auto; mix-blend-mode: multiply; }
.footer-links, .footer-contact { display: flex; flex-wrap: wrap; gap: 0 20px; font: 400 .8125rem var(--mono); }
.footer-links a, .footer-contact a { display: inline-flex; align-items: center; min-height: 44px; text-underline-offset: 4px; }
.footer-links a:hover, .footer-contact a:hover { text-decoration-thickness: 2px; }
.footer-time, .footer-copy { font: 400 .8125rem var(--mono); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0s !important; transition-duration: 0s !important; }
}

/* ---------- Swarm build-in (swarm.js): first visit per session, motion allowed ----------
   Blocks are hidden with opacity only, so they stay in layout, in the accessibility tree and clickable. */
/* Before the swarm starts only what it will build is hidden: the Opening's copy paints at once. */
.sw:not(.sw-on) main > :not(.opening), .sw:not(.sw-on) .stack, .sw:not(.sw-on) .masthead-mark, .sw:not(.sw-on) .footer-inner { opacity: 0; }
.sw.sw-on .sw-p { opacity: 0; }
@media print { .sw main > *, .sw .stack, .sw .masthead-mark, .sw .footer-inner, .sw .sw-p { opacity: 1 !important; } }
.sw-layer { position: absolute; left: 0; top: 0; width: 100%; height: 0; overflow-x: clip; z-index: 90; pointer-events: none; }
.sw-layer > * { position: absolute; left: 0; top: 0; }
.sw-cur { will-change: transform; }
.sw-cur svg { position: absolute; display: none; overflow: visible; max-width: none; }
.sw-cur[data-mode="arrow"] .sw-arrow, .sw-cur[data-mode="cross"] .sw-cross, .sw-cur[data-mode="text"] .sw-ibeam { display: block; }
.sw-arrow { left: -1px; top: -1px; }
.sw-arrow path { fill: var(--c); stroke: var(--paper); stroke-width: 1.25; stroke-linejoin: round; }
.sw-cross { left: -9.5px; top: -9.5px; }
.sw-ibeam { left: -5px; top: -10px; }
.sw-cross path, .sw-ibeam path { fill: none; stroke: var(--c); stroke-width: 1.5; }
.sw-cross path.u, .sw-ibeam path.u { stroke: var(--paper); stroke-width: 4; stroke-linecap: square; }
.sw-name, .sw-badge {
  position: absolute; background: var(--c); color: var(--paper);
  font: 500 11px/1 var(--mono); padding: 4px 6px; border-radius: 2px; white-space: nowrap;
}
.sw-name { left: 14px; top: 19px; background: var(--ink); }
.sw-badge { left: 0; top: 0; }
.sw-line { position: absolute; left: 0; top: 0; background: var(--c); transform-origin: 0 0; }
.sw-h { height: 1px; }
.sw-v { width: 1px; }
.sw-handle { position: absolute; left: -3.5px; top: -3.5px; width: 7px; height: 7px; background: var(--paper); border: 1px solid var(--c); }
.sw-cover { background: var(--paper) var(--grain); transform-origin: 0 100%; }
.sw-guide { width: 1px; background: var(--c); }
.sw-clone { margin: 0; box-sizing: border-box; }
.sw-rest { color: transparent; }
.sw-caret { position: relative; }
.sw-caret::after { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; background: var(--c); }
.sw-clone.is-idle .sw-caret::after { animation: sw-blink .5s steps(1) infinite; }
@keyframes sw-blink { 50% { opacity: 0; } }
/* Skip sits in the masthead band, right of the wordmark, so it never covers the content column. */
.sw-skip { position: fixed; right: var(--gutter); top: calc((var(--header-h) - 44px) / 2); z-index: 95; background: var(--paper); }
/* The compact build (below 1280 px, swarm.js) is about two seconds in the header: too short to need a Skip button,
   and its name tags sit beside the arrow tip, so they stay inside the header instead of hanging below it. */
.sw-compact .sw-skip { display: none; }
.sw-compact .sw-name { left: 17px; top: -10px; } /* centred on the tip: inside the header even at the drag's end (y 54) */
