/* Nowei's site. The company page of the family, on the same night isogram's site stands on: one
   black ground from the top of the page to the foot, whatever the visitor's own setting, so the
   company and its products read as one house. The letters are isogram's too (Inter Tight for
   headlines, Inter for reading, IBM Plex Mono for the small labels that name things). One accent,
   the blue of the dot in the wordmark; each product keeps its own colour on its own name. */
:root {
  --ground: #0a0b0d;
  --raise: #121316;
  --ink: #f3f4f6;
  --ink-2: #a3a8b0;
  --ink-3: #80858e;
  --hair: rgba(255, 255, 255, 0.08);
  --hair-2: rgba(255, 255, 255, 0.15);
  --accent: #6f9bff;
  --glass: rgba(10, 11, 13, 0.66);
  --shade: 0 1px 2px rgba(0, 0, 0, 0.4), 0 30px 70px -30px rgba(0, 0, 0, 0.8);
  --btn: #f3f4f6;
  --on-btn: #0a0b0d;
  --display: "Inter Tight", "Inter", system-ui, -apple-system, sans-serif;
  --sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, Menlo, monospace;
  --ease: cubic-bezier(0.2, 0.7, 0.1, 1);
  --page: 1240px;
  --gutter: clamp(20px, 4vw, 56px);
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 80px; }
html, body { overflow-x: clip; }
body {
  margin: 0; background: var(--ground); color: var(--ink);
  font: 400 17px/1.55 var(--sans); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3, p, dl, dd, figure { margin: 0; }
h1, h2 { font-family: var(--display); font-weight: 600; letter-spacing: -0.045em; line-height: 0.98; text-wrap: balance; }
h1 { font-size: clamp(48px, min(8vw, 13vh), 112px); }
h2 { font-size: clamp(36px, 5vw, 68px); }
h3 { font: 600 22px/1.2 var(--display); letter-spacing: -0.02em; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 6px; }
::selection { background: color-mix(in oklab, var(--accent) 28%, transparent); }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } *, *::before, *::after { transition: none !important; animation: none !important; } }

.wrap { width: min(var(--page), 100% - var(--gutter) * 2); margin-inline: auto; }
.block { padding-block: clamp(88px, 11vw, 160px); border-top: 1px solid var(--hair); }
/* A thing's label, lettered small and mono the way a drawing names its views. */
.fig { font: 500 12px/1.4 var(--mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.lede { font-size: clamp(18px, 1.6vw, 22px); line-height: 1.45; color: var(--ink-2); letter-spacing: -0.01em; text-wrap: balance; }
.skip { position: absolute; left: 12px; top: -60px; padding: 10px 14px; background: var(--btn); color: var(--on-btn); border-radius: 10px; z-index: 30; }
.skip:focus { top: 12px; }

/* ── Header: no bar, just the wordmark and three links standing on the page. On the home page it
   stands over the relief, so it lies on top of the stage rather than above it. ── */
.top { position: relative; z-index: 20; }
.top.over-stage { position: absolute; inset: 0 0 auto; }
.top .wrap { display: flex; align-items: center; justify-content: space-between; height: 68px; }
.word { font: 600 24px/1 var(--display); letter-spacing: -0.055em; }
.word i { font-style: normal; color: var(--accent); }
.top nav { display: flex; gap: clamp(18px, 3vw, 36px); font-size: 15px; color: var(--ink-2); }
.top .wrap { height: 88px; }
.top nav a { transition: color 0.2s; }
.top nav a:hover { color: var(--ink); }
@media (max-width: 520px) { .top nav a.hide-narrow { display: none; } }

/* ── Hero ── */
.hero { padding-block: clamp(80px, 13vh, 150px) clamp(72px, 11vh, 130px); }
.hero .fig { display: flex; gap: 10px; align-items: center; margin-bottom: 28px; }
.hero .fig::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.hero .lede { max-width: 620px; margin-top: 28px; }
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 40px; }
.btn {
  display: inline-flex; align-items: center; gap: 10px; height: 48px; padding: 0 22px; border-radius: 999px;
  background: var(--btn); color: var(--on-btn); font-weight: 500; border: 0; cursor: pointer;
  transition: transform 0.25s var(--ease), opacity 0.2s;
}
.btn:hover { transform: translateY(-1px); }
.btn.ghost { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1px var(--hair-2); }
.btn .arrow { transition: transform 0.3s var(--ease); }
.btn:hover .arrow.down { transform: translateY(3px); }
.btn:hover .arrow.out { transform: translate(2px, -2px); }

/* ── Applications: each product seen through a pane of glass ── */
.head { display: flex; justify-content: space-between; align-items: end; gap: 24px; margin-bottom: clamp(40px, 5vw, 64px); }
.head h2 { margin-top: 14px; }
.apps { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(24px, 3vw, 40px); }
@media (max-width: 860px) { .apps { grid-template-columns: 1fr; } }

/* A screenshot pane: crisp and rounded, with a hairline at its edge, standing on the page's black.
   A glow behind it was tried and dropped: it greyed the black. */
.pane { position: relative; }
.window {
  position: relative; display: block; aspect-ratio: 16 / 10; border-radius: 18px; overflow: hidden; isolation: isolate;
  background: var(--raise); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 30px 80px -40px rgba(0, 0, 0, 0.9);
  transition: transform 0.5s var(--ease);
}
/* The foot of a site screenshot fades into the page's black, as if the page it shows carries on
   below. With nothing behind the pane, the fade lands on pure black. */
.window:not(.phone) { -webkit-mask-image: linear-gradient(180deg, #000 68%, transparent 100%); mask-image: linear-gradient(180deg, #000 68%, transparent 100%); }
/* The hairline drawn over the picture, so it stays crisp against the black above the fade. */
.window::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1); pointer-events: none; z-index: 2; }
.pane:hover .window { transform: translateY(-4px); }
/* The site itself, whole: the pane has the picture's own shape (16:10), so nothing is cropped. */
.window .site { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; }
/* "Visit site": no button at rest. On hover it rises into the middle of the picture while the
   picture dims behind it, so the label is plain to see and the page is still recognisable. */
.window .site { transition: filter 0.45s var(--ease); }
.pane:hover .window .site, .window:focus-visible .site { filter: brightness(0.38) saturate(0.8); }
.visit {
  position: absolute; left: 50%; top: 50%; z-index: 3; display: inline-flex; align-items: center; gap: 8px;
  height: 44px; padding: 0 20px; border-radius: 999px; font: 500 15px/1 var(--sans);
  background: #f3f4f6; color: #0a0b0d; box-shadow: 0 10px 30px -8px rgba(0, 0, 0, 0.7);
  opacity: 0; transform: translate(-50%, calc(-50% + 8px)); pointer-events: none;
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
}
.pane:hover .visit, .window:focus-visible .visit { opacity: 1; transform: translate(-50%, -50%); }
/* On a touch screen there is no hover: the picture itself is the link, as it always was. */
@media (hover: none) { .visit { display: none; } }

.about { display: grid; grid-template-columns: 1fr auto; gap: 8px 24px; padding: 26px 4px 0; }
.name { display: inline-flex; align-items: center; gap: 9px; font: 600 28px/1 var(--display); letter-spacing: -0.045em; }
.name:hover { color: var(--accent); }
.name .bloom { width: 22px; height: 22px; fill: #b3a1ef; overflow: visible; }
/* Gati's own logo, the star before the wordmark, both drawn from Gati's brand files in its blue. */
.name.gati { color: #7aa2ff; gap: 8px; }
.name.gati .star { width: 19px; height: 19px; fill: currentColor; margin-top: -3px; }
.name.gati .word { height: 27px; width: auto; aspect-ratio: 961 / 537; fill: currentColor; margin-top: 4px; }
.status { align-self: center; font: 500 12px/1 var(--mono); letter-spacing: 0.04em; color: var(--ink-3); display: inline-flex; align-items: center; gap: 8px; }
.status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.status.live { color: #3ecf7a; }
.about p { grid-column: 1 / -1; color: var(--ink-2); max-width: 520px; }
.links { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px 24px; margin-top: 10px; font-size: 15px; font-weight: 500; }
.links a { display: inline-flex; gap: 6px; border-bottom: 1px solid var(--hair-2); padding-bottom: 2px; transition: border-color 0.2s; }
.links a:hover { border-color: var(--ink); }

/* ── Company: what we are, then the facts a registry would want ── */
.company { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: clamp(40px, 7vw, 110px); }
@media (max-width: 860px) { .company { grid-template-columns: 1fr; } }
.company h2 { margin: 14px 0 28px; }
.company .lede + .lede { margin-top: 18px; }
.facts { border-top: 1px solid var(--ink); align-self: start; }
.facts div { display: grid; grid-template-columns: 150px 1fr; gap: 16px; padding: 18px 0; border-bottom: 1px solid var(--hair); font-size: 15.5px; }
.facts dt { font: 500 12px/1.6 var(--mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.facts dd { color: var(--ink); }
.principles { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(24px, 3vw, 40px); margin-top: clamp(64px, 8vw, 110px); }
@media (max-width: 860px) { .principles { grid-template-columns: 1fr; } }
.principles article { padding-top: 22px; border-top: 1px solid var(--hair-2); }
.principles .fig { display: block; margin-bottom: 18px; }
.principles h3 { margin-bottom: 10px; }
.principles p { color: var(--ink-2); font-size: 16px; }

/* ── Contact ── */
.contact { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: clamp(40px, 7vw, 110px); }
@media (max-width: 860px) { .contact { grid-template-columns: 1fr; } }
.contact h2 { margin: 14px 0 24px; }
.lines { margin-top: 40px; display: grid; gap: 22px; }
.lines div { display: grid; gap: 4px; }
.lines a { font-weight: 500; }
.lines a:hover { color: var(--accent); }

/* ── Foot ── */
.foot { border-top: 1px solid var(--hair); padding-block: 48px 56px; font-size: 14px; color: var(--ink-3); }
.foot .wrap { display: grid; grid-template-columns: 1fr auto; gap: 18px 40px; align-items: start; }
.foot .word { color: var(--ink); font-size: 22px; }
.foot nav { display: flex; flex-wrap: wrap; gap: 8px 22px; }
.foot nav a:hover { color: var(--ink); }
.foot .legal { grid-column: 1 / -1; line-height: 1.7; }
@media (max-width: 640px) { .foot .wrap { grid-template-columns: 1fr; } }

/* Things arrive once as they are scrolled to, a short rise and fade, never again. */
.rise { opacity: 0; transform: translateY(18px); transition: opacity 0.9s var(--ease), transform 0.9s var(--ease); }
.rise.seen { opacity: 1; transform: none; }
.no-js .rise { opacity: 1; transform: none; }
/* On a narrow window the address centres in the space beside the lights instead of the whole bar. */
@media (max-width: 560px) { .address { transform: none; margin-inline: 0; } }

/* ── The relief stage (js/relief.js), on the page's own black. Tall, so the pinned canvas holds while the land
   arrives; --p is how far through it the reader is, set by the script. ── */
.stage { position: relative; height: 220vh; background: var(--ground); }
.pin { position: sticky; top: 0; height: 100vh; overflow: hidden; }
.pin canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
/* A soft vignette so the land fades into the black at the edges rather than stopping there. */
.pin::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(75% 70% at 50% 50%, transparent 35%, rgba(10, 11, 13, 0.7) 70%, var(--ground) 100%),
    linear-gradient(90deg, var(--ground) 0, transparent 18%, transparent 82%, var(--ground) 100%),
    linear-gradient(180deg, var(--ground) 0, transparent 16%, transparent 80%, var(--ground) 100%);
}
.over {
  position: absolute; inset: 0; z-index: 1; display: grid; place-content: center; text-align: center; gap: 20px; padding: 0 var(--gutter);
  animation: arrive 1.4s var(--ease) 0.2s both;
}
/* A pool of the ground under the words, so the land dims where it would fight the letters. */
.over::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(38% 30% at 50% 50%, rgba(10, 11, 13, 0.82), rgba(10, 11, 13, 0.45) 60%, transparent 100%);
}
.over .fig { color: #c4d6ff; }
.over .line { font-size: clamp(48px, min(8vw, 13vh), 120px); line-height: 0.96; text-shadow: 0 2px 30px rgba(10, 11, 13, 0.9); }
@keyframes arrive { from { opacity: 0; transform: translateY(14px); } }
.down {
  position: absolute; left: 50%; bottom: 36px; z-index: 1; transform: translateX(-50%);
  font: 500 12px/1 var(--mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-2);
  display: inline-flex; gap: 10px; transition: color 0.2s;
}
.down:hover { color: var(--ink); }
.head .lede { max-width: 620px; margin-top: 26px; }
.stage + .block { border-top: 0; }
@media (prefers-reduced-motion: reduce) { .stage { height: 100vh; } }

/* ── Contact band on the home page: one line and the way to the contact page ── */
.reach { display: grid; grid-template-columns: 1fr 1fr; gap: 32px clamp(40px, 7vw, 110px); align-items: end; }
@media (max-width: 860px) { .reach { grid-template-columns: 1fr; } }
.reach h2 { margin-top: 14px; }
.reach-go { display: grid; gap: 26px; justify-items: start; }

/* ── The contact page ── */
.page { padding-block: clamp(64px, 10vh, 120px) clamp(88px, 12vh, 150px); }
.page-title { font-size: clamp(44px, 6vw, 80px); margin: 14px 0 24px; }
.top nav a[aria-current="page"] { color: var(--ink); }
.reach-page { max-width: 720px; }
.mail { margin: 40px 0 56px; display: grid; gap: 18px; justify-items: start; }
.reveal[aria-expanded="true"] { display: none; }
.address-art { display: block; max-width: 100%; }
.address-art[hidden] { display: none; }

/* While a window's picture arrives in cells (js/cells.js) the canvas stands in for the img, in the
   same place and at the same scale; the img comes back once the picture is whole. */
.window .cells { background: transparent; }
.window.celling img.site { opacity: 0; }

/* ── The analytics question (js/consent.js), as on isogram's site: a small card at the foot of the
   screen; Accept and Decline one size and weight, so neither is the easy one. ── */
.consent {
  position: fixed; z-index: 60; inset: auto 10px calc(10px + env(safe-area-inset-bottom)) 10px;
  padding: 11px 12px 10px; border-radius: 14px; background: #17181b; color: var(--ink);
  box-shadow: 0 0 0 1px var(--hair-2), 0 24px 60px -20px rgba(0, 0, 0, 0.8);
  opacity: 0; transform: translateY(12px); transition: opacity 0.2s, transform 0.3s var(--ease);
}
.consent.shown { opacity: 1; transform: none; }
.consent-words { margin: 0 0 9px; font: 12.5px/1.45 var(--sans); color: var(--ink-2); }
.consent-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.consent-btn {
  flex: 1 1 0; min-width: 6em; height: 32px; padding: 0 14px; border: 0; border-radius: 999px; cursor: pointer;
  background: transparent; color: var(--ink); font: 500 13.5px/1 var(--sans);
  box-shadow: inset 0 0 0 1px var(--hair-2); transition: background 0.2s, box-shadow 0.2s;
}
.consent-btn:hover { background: rgba(255, 255, 255, 0.08); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3); }
.consent-more { flex: 0 0 auto; padding: 0 6px; font: 11.5px/1 var(--mono); color: var(--ink-3); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--hair-2); }
.consent-more:hover { color: var(--ink-2); }
@media (min-width: 641px) {
  .consent { inset: auto auto 16px 16px; width: min(360px, calc(100vw - 32px)); }
  .consent-btn { flex: 0 1 auto; }
}
.foot button.linkish { background: none; border: 0; padding: 0; color: inherit; font: inherit; cursor: pointer; }
.foot button.linkish:hover { color: var(--ink); }

/* ── A product page (isogram.html, gati.html, written by tools/pages.py) ── */
.product { padding-block: clamp(48px, 8vh, 96px) clamp(72px, 10vh, 120px); }
.back { display: inline-block; margin-bottom: 40px; font: 500 12px/1 var(--mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.back:hover { color: var(--ink); }
.product-head { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; }
.product .lede { max-width: 660px; }
.product .links { margin-top: 26px; }
.product-shot { margin-top: clamp(48px, 7vw, 88px); }
.facts.wide { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--ink); }
.facts.wide div { grid-template-columns: 1fr; gap: 8px; border-bottom: 0; padding-right: 16px; }
@media (max-width: 760px) { .facts.wide { grid-template-columns: 1fr 1fr; } }
.studies { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 4vw, 48px) clamp(24px, 3vw, 40px); }
.study.wide { grid-column: 1 / -1; }
@media (max-width: 760px) { .studies { grid-template-columns: 1fr; } }
.study figcaption, .phone-shot figcaption { padding: 22px 4px 0; }
.study .fig, .phone-shot .fig { display: block; margin-bottom: 12px; }
.study h3 { margin-bottom: 8px; }
.study p, .phone-shot p { color: var(--ink-2); max-width: 520px; }
.study .window, .study.wide .window { aspect-ratio: 16 / 10; }

.phones { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 3vw, 40px); margin-bottom: clamp(56px, 7vw, 96px); }
@media (max-width: 760px) { .phones { grid-template-columns: 1fr 1fr; } }
.window.phone { aspect-ratio: 9 / 16; border-radius: 28px; }
.phone-shot p { font: 600 19px/1.25 var(--display); letter-spacing: -0.02em; color: var(--ink); }
.principles.six { margin-top: 0; }
.head h2 + .lede { margin-top: 26px; }

/* ── Plain reading pages (privacy.html) ── */
.prose { max-width: 760px; }
.prose h2 { font-size: clamp(24px, 2.4vw, 30px); letter-spacing: -0.025em; margin: 48px 0 14px; }
.prose p { color: var(--ink-2); }
.prose a { color: var(--ink); border-bottom: 1px solid var(--hair-2); }
.prose a:hover { border-color: var(--ink); }
