/* DailyOKC — site styles.
   Layout rule that keeps this file predictable: .beat owns all section
   spacing and nothing else ever sets it. The .beat--* modifiers change
   colour only. That is what stops two selectors quietly cancelling each
   other's padding. */

/* ===== reset ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body, h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd { margin: 0; }
ul[class], ol[class] { list-style: none; padding: 0; }
img, picture, canvas, svg { display: block; max-width: 100%; }
button, input, textarea, select { font: inherit; color: inherit; }
:where(a) { color: inherit; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--body);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--on-ink);
  background: var(--ink);
  overflow-x: hidden;
  /* Fallback ground for no-WebGL: the day cycle as a plain gradient, so the
     page is never a flat black rectangle. */
  background-image: linear-gradient(180deg, #2e2a6b 0%, #ff6fa0 22%, #7fc5e8 45%, #ff9e5e 68%, #17123a 100%);
  background-attachment: fixed;
}

h1, h2, h3, .display {
  font-family: var(--display);
  font-weight: 800;
  font-stretch: 92%;
  line-height: 0.88;
  letter-spacing: -0.028em;
  text-wrap: balance;
}

::selection { background: var(--hibiscus); color: #fff; }

:focus-visible {
  outline: 3px solid var(--sun);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

/* ===== helpers ========================================================== */
.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}

.shell--wide { max-width: 1560px; }

.skip {
  position: absolute;
  left: -9999px;
  z-index: 200;
}
.skip:focus {
  left: 1rem;
  top: 1rem;
  padding: 0.7rem 1rem;
  background: var(--sun);
  color: #000;
  font-family: var(--mono);
  font-size: var(--step--1);
}

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

/* ===== the WebGL bed ==================================================== */
#sky {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

.page { position: relative; z-index: 1; }

/* ===== timestamp stamp =================================================
   The structural device. Every section is a moment in one working day; the
   track is the day from 06:00 to 22:00 and the dot sits at this section's
   hour. So the marker reports real position in a real sequence — the same
   hour the sky behind it is rendering — rather than decorating. --pos is set
   inline per section because it is content, not styling. */
.stamp {
  display: flex;
  align-items: center;
  gap: clamp(0.6rem, 0.4rem + 0.7vw, 1.1rem);
  font-family: var(--mono);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: clamp(1.5rem, 1rem + 2vw, 3rem);
}

.stamp__time {
  color: var(--hibiscus);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  flex: none;
}

/* The track is only a positioning context. The rule is a separate child so the
   reveal can scale the line without squashing the dot sitting on top of it. */
.stamp__track {
  position: relative;
  flex: 1 1 auto;
  max-width: 260px;
  height: 1px;
}

.stamp__rule {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, currentColor 30%, transparent);
  transform-origin: left center;
}

.stamp__dot {
  position: absolute;
  top: 50%;
  left: clamp(0%, calc(var(--pos, 0.5) * 100%), 100%);
  width: 9px; height: 9px;
  margin: -4.5px 0 0 -4.5px;
  border-radius: 50%;
  background: var(--sun);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sun) 28%, transparent),
              0 0 18px color-mix(in srgb, var(--sun) 70%, transparent);
}

.stamp__name { flex: none; opacity: 0.75; }

/* ===== nav ============================================================== */
.nav {
  position: fixed;
  /* --bar-h is the motion bar's height, set by js/motion.js only when that bar
     is actually on the page. Without it the nav sits flush at the top. */
  top: var(--bar-h, 0px);
  right: 0;
  left: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  gap: var(--gap);
  padding: 0.85rem var(--pad-x);
  background: color-mix(in srgb, var(--ink) 62%, transparent);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  border-bottom: 1px solid color-mix(in srgb, #fff 10%, transparent);
  transition: transform var(--t-med) var(--ease);
}

.nav--hidden { transform: translateY(-105%); }

.mark {
  font-family: var(--display);
  font-weight: 800;
  font-stretch: 78%;
  font-size: var(--step-1);
  letter-spacing: -0.03em;
  line-height: 1;
  text-decoration: none;
  flex: none;
}

.mark b { color: var(--hibiscus); font-weight: inherit; }

.nav__links {
  display: flex;
  gap: clamp(0.9rem, 0.4rem + 1.2vw, 2rem);
  margin-left: auto;
  font-family: var(--mono);
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.nav__links a {
  text-decoration: none;
  padding-block: 0.35rem;
  position: relative;
  color: var(--on-ink-soft);
  transition: color var(--t-fast) var(--ease);
}

.nav__links a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 2px;
  background: var(--hibiscus);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-fast) var(--ease);
}

.nav__links a:hover, .nav__links a:focus-visible { color: var(--on-ink); }
.nav__links a:hover::after, .nav__links a:focus-visible::after { transform: scaleX(1); }

/* The clock reports the hour the sky is rendering, so the nav, the section
   stamps and the shader all state the same time. */
.nav__clock {
  flex: none;
  margin-left: clamp(0.75rem, 0.3rem + 1.4vw, 2rem);
  padding: 0.3rem 0.7rem;
  border-radius: 100px;
  background: color-mix(in srgb, var(--hibiscus) 16%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--hibiscus) 45%, transparent);
  font-family: var(--mono);
  font-size: var(--step--1);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--sun);
}

/* ===== buttons ========================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.5rem;
  border: 0;
  border-radius: 100px;
  font-family: var(--mono);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease),
              background-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease);
}

.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--go { background: var(--hibiscus); color: #fff; }
.btn--go:hover { background: #ff5596; }

.btn--ghost {
  background: transparent;
  color: currentColor;
  box-shadow: inset 0 0 0 1.5px currentColor;
}
.btn--ghost:hover { background: currentColor; color: var(--ink); }

.btn__arrow { transition: transform var(--t-fast) var(--ease); }
.btn:hover .btn__arrow { transform: translateX(4px); }

/* ===== hero ============================================================= */
.hero {
  position: relative;
  /* The motion bar, when present, takes height off the top of the window.
     Without this subtraction the hero's own call to action gets clipped for
     exactly the visitors who already had a degraded experience. */
  min-height: calc(100svh - var(--bar-h, 0px));
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  /* The top pad clears the fixed nav, and the nav itself sits below the motion
     bar — so the bar's height has to be added here too, or the 06:12 stamp is
     the thing that ends up underneath it. */
  padding-block:
    calc(clamp(4.75rem, 3.5rem + 3vw, 6.5rem) + var(--bar-h, 0px))
    clamp(2rem, 1rem + 3vw, 3.5rem);
}

/* A scrim so the headline survives whatever the sky is doing behind it. It has
   to hold at first light, when the mid-band is bright cyan and orange — that
   is the hour where white text fails, not the night. Weighted to the bottom,
   where the copy actually sits, so the top of the sky stays clear. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg,
      transparent 0%,
      color-mix(in srgb, var(--ink) 18%, transparent) 32%,
      color-mix(in srgb, var(--ink) 68%, transparent) 62%,
      color-mix(in srgb, var(--ink) 90%, transparent) 100%),
    radial-gradient(95% 70% at 8% 88%,
      color-mix(in srgb, var(--ink) 72%, transparent) 0%,
      transparent 72%);
  pointer-events: none;
}

.hero > * { position: relative; }

.hero__head {
  font-size: var(--step-5);
  font-stretch: 88%;
  max-width: 15ch;
}

/* Each line is wrapped so it can be revealed from behind its own edge. */
.line { display: block; overflow: hidden; }
.line > span { display: block; }

.hero__daily {
  color: var(--hibiscus);
  font-style: normal;
  font-stretch: 100%;
  letter-spacing: -0.04em;
}

.hero__sub {
  margin-top: clamp(1.25rem, 1rem + 1.5vw, 2rem);
  max-width: 54ch;
  font-size: var(--step-1);
  line-height: 1.45;
  color: var(--on-ink);
  text-shadow: 0 1px 24px color-mix(in srgb, var(--ink) 80%, transparent);
}

.hero__sub b { color: var(--pool); font-weight: 600; }

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: clamp(1.5rem, 1rem + 2vw, 2.5rem);
}

/* ===== ticker =========================================================== */
.ticker {
  position: relative;
  z-index: 1;
  overflow: hidden;
  padding-block: 0.7rem;
  background: var(--hibiscus);
  color: #fff;
  border-block: 1px solid color-mix(in srgb, #000 25%, transparent);
}

.ticker__row {
  display: flex;
  width: max-content;
  gap: 0;
  will-change: transform;
}

.ticker__set {
  display: flex;
  gap: 2.5rem;
  padding-right: 2.5rem;
  font-family: var(--mono);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
}

.ticker__set span::before {
  content: "◆";
  margin-right: 2.5rem;
  opacity: 0.5;
}

/* ===== beats ============================================================ */
.beat {
  position: relative;
  padding-block: var(--beat-y);
}

/* Open beats sit directly on the WebGL sky. They need a scrim or the body copy
   has to compete with whatever hour is rendering behind it — midday is the
   bright one that breaks legibility first. */
.beat--open {
  color: var(--on-ink);
  isolation: isolate;
}

.beat--open::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg,
              transparent 0%,
              color-mix(in srgb, var(--ink) 72%, transparent) 14%,
              color-mix(in srgb, var(--ink) 80%, transparent) 86%,
              transparent 100%);
  pointer-events: none;
}

.beat--panel {
  background: var(--porcelain);
  color: var(--on-light);
}

.beat--ink {
  background: var(--ink);
  color: var(--on-ink);
}

.beat--panel .stamp__name { color: var(--on-light-soft); opacity: 1; }
.beat--panel .stamp__dot { background: var(--dusk); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dusk) 22%, transparent); }

.beat__head {
  font-size: var(--step-4);
  max-width: 22ch;
}

/* In a split layout the heading only has half the width, so step-4 gives it
   about seven characters a line. These sections drop a step. */
.svc .beat__head,
.contact .beat__head {
  font-size: var(--step-3);
  max-width: 20ch;
}

.beat__lede {
  margin-top: clamp(1rem, 0.8rem + 1vw, 1.75rem);
  max-width: 54ch;
  font-size: var(--step-1);
  line-height: 1.5;
}

.beat--panel .beat__lede { color: var(--on-light-soft); }
.beat--ink .beat__lede, .beat--open .beat__lede { color: var(--on-ink-soft); }

/* ===== the board (service overview) ==================================== */
.board {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 270px), 1fr));
  gap: var(--gap);
  margin-top: clamp(2rem, 1.5rem + 3vw, 4rem);
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 340px;
  padding: 1.4rem;
  border-radius: var(--r-md);
  overflow: hidden;
  isolation: isolate;
  background: var(--ink-2);
  color: var(--on-ink);
  text-decoration: none;
  transition: transform var(--t-med) var(--ease);
}

.card:hover { transform: translateY(-6px); }

.card__img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1.1s var(--ease), filter var(--t-med) var(--ease);
  filter: saturate(0.85) contrast(1.05);
}

.card:hover .card__img { transform: scale(1.07); filter: saturate(1.1) contrast(1.05); }

.card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  /* Kept off the top third: the photograph is the point of these cards, and a
     scrim heavy enough for the name does not need to cover the whole frame. */
  background: linear-gradient(190deg,
              color-mix(in srgb, var(--ink) 8%, transparent) 0%,
              color-mix(in srgb, var(--ink) 55%, transparent) 48%,
              color-mix(in srgb, var(--ink) 92%, transparent) 78%,
              var(--ink) 100%);
}

.card__no {
  font-family: var(--mono);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--pool);
}

.card__name {
  margin-top: auto;
  font-size: var(--step-2);
  font-stretch: 84%;
}

.card__note {
  margin-top: 0.6rem;
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--on-ink-soft);
}

.card__go {
  margin-top: 1rem;
  font-family: var(--mono);
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--hibiscus);
}

/* ===== service beat (split) ============================================ */
.svc {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  gap: clamp(1.75rem, 1rem + 4vw, 5rem);
  align-items: center;
}

.svc__body { min-width: 0; }
.svc__media { min-width: 0; }

.svc--flip .svc__media { order: -1; }

.svc__list {
  margin-top: clamp(1.25rem, 1rem + 1.5vw, 2rem);
  display: grid;
  gap: 0.1rem;
}

.svc__list li {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  padding-block: 0.75rem;
  border-top: 1px solid color-mix(in srgb, currentColor 18%, transparent);
  font-size: var(--step-0);
}

.svc__list li:last-child { border-bottom: 1px solid color-mix(in srgb, currentColor 18%, transparent); }

.svc__list b {
  flex: none;
  width: 2.2rem;
  font-family: var(--mono);
  font-size: var(--step--1);
  font-weight: 700;
  color: var(--hibiscus);
}

/* ===== image stacks ==================================================== */
.stack {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gap);
}

.stack__f {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--ink-2);
}

.stack__f img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* No aspect-ratio here on purpose. The two square siblings set the row heights,
   and this one stretches across both — pinning a ratio as well makes it end
   short of them and the column bottoms stop aligning. */
.stack__f--tall { grid-row: span 2; min-height: 300px; }
.stack__f--sq { aspect-ratio: 1; }
.stack__f--wide { grid-column: span 2; aspect-ratio: 16 / 9; }

.stack__cap {
  position: absolute;
  left: 0; bottom: 0;
  padding: 0.5rem 0.8rem;
  background: var(--ink);
  color: var(--on-ink);
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border-radius: 0 var(--r-sm) 0 0;
}

/* a single full-bleed photograph used as a divider between beats */
.bleed {
  position: relative;
  height: clamp(280px, 42vw, 560px);
  overflow: hidden;
}

.bleed img {
  width: 100%;
  height: 130%;
  object-fit: cover;
  will-change: transform;
}

.bleed__quote {
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--pad-x);
  background: linear-gradient(0deg, color-mix(in srgb, var(--ink) 92%, transparent), transparent);
  font-family: var(--display);
  font-weight: 800;
  font-stretch: 86%;
  font-size: var(--step-3);
  line-height: 0.95;
  letter-spacing: -0.03em;
  color: #fff;
  text-wrap: balance;
}

.bleed__quote em { color: var(--sun); font-style: normal; }

/* ===== wrap (deliverables) ============================================= */
.wrap {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: var(--gap);
  margin-top: clamp(2rem, 1.5rem + 3vw, 3.5rem);
}

.wrap__item {
  padding: 1.5rem 1.4rem;
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--porcelain) 8%, transparent);
  border: 1px solid color-mix(in srgb, #fff 12%, transparent);
}

.wrap__n {
  font-family: var(--mono);
  font-size: var(--step-2);
  font-weight: 700;
  color: var(--pool);
  line-height: 1;
}

.wrap__t {
  margin-top: 0.9rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--step-1);
  font-stretch: 88%;
  line-height: 1.05;
}

.wrap__d {
  margin-top: 0.5rem;
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--on-ink-soft);
}

/* ===== contact ========================================================= */
.contact {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: clamp(2rem, 1rem + 4vw, 5rem);
  align-items: start;
}

.form { display: grid; gap: 1rem; }

.field { display: grid; gap: 0.4rem; }

.field > span {
  font-family: var(--mono);
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--on-ink-soft);
}

.field input, .field textarea, .field select {
  width: 100%;
  padding: 0.85rem 1rem;
  border: 1px solid color-mix(in srgb, #fff 18%, transparent);
  border-radius: var(--r-sm);
  background: color-mix(in srgb, #fff 5%, transparent);
  color: var(--on-ink);
  transition: border-color var(--t-fast) var(--ease),
              background-color var(--t-fast) var(--ease);
}

.field input:focus, .field textarea:focus, .field select:focus {
  border-color: var(--hibiscus);
  background: color-mix(in srgb, #fff 9%, transparent);
}

.field textarea { min-height: 130px; resize: vertical; }

.form__note {
  font-size: var(--step--1);
  color: var(--on-ink-soft);
}

.dl { display: grid; gap: 1.4rem; margin-top: clamp(1.5rem, 1rem + 2vw, 2.5rem); }

.dl__k {
  font-family: var(--mono);
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--on-ink-soft);
}

.dl__v {
  font-family: var(--display);
  font-weight: 700;
  font-stretch: 88%;
  font-size: var(--step-2);
  line-height: 1.05;
  margin-top: 0.2rem;
}

.dl__v a { text-decoration: none; border-bottom: 2px solid var(--hibiscus); }
.dl__v a:hover { color: var(--hibiscus); }

/* ===== footer ========================================================== */
.foot {
  position: relative;
  z-index: 1;
  padding: clamp(2.5rem, 2rem + 3vw, 4rem) 0 2rem;
  background: var(--ink);
  border-top: 1px solid var(--ink-3);
}

.foot__grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap) clamp(1.5rem, 1rem + 3vw, 4rem);
  align-items: flex-start;
  justify-content: space-between;
}

.foot__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  font-family: var(--mono);
  font-size: var(--step--1);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.foot__links a { color: var(--on-ink-soft); text-decoration: none; }
.foot__links a:hover { color: var(--hibiscus); }

.foot__fine {
  margin-top: 2.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--ink-3);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  color: var(--on-ink-soft);
}

.foot__fine a { color: var(--on-ink-soft); }

/* ===== document pages ==================================================
   credits.html and 404.html. No WebGL bed on these, so they carry the ink
   ground themselves and get a plain top offset instead of a hero. */
.doc { background-image: none; background: var(--ink); }

.doc .page { padding-top: clamp(3.5rem, 3rem + 2vw, 5rem); }

.doc__h {
  margin-top: clamp(2.5rem, 2rem + 2vw, 4rem);
  font-family: var(--display);
  font-weight: 800;
  font-stretch: 88%;
  font-size: var(--step-2);
  letter-spacing: -0.02em;
}

/* Wide tables scroll in their own box rather than pushing the page sideways. */
.doc__scroll {
  overflow-x: auto;
  margin-top: 1.25rem;
  border: 1px solid var(--ink-3);
  border-radius: var(--r-md);
}

.doc__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step--1);
}

.doc__table th,
.doc__table td {
  padding: 0.7rem 0.9rem;
  text-align: left;
  border-bottom: 1px solid var(--ink-3);
  white-space: nowrap;
}

.doc__table th {
  font-family: var(--mono);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pool);
  background: var(--ink-2);
}

.doc__table tr:last-child td { border-bottom: 0; }
.doc__table td:nth-child(2) { white-space: normal; min-width: 18ch; }
.doc__table code { font-family: var(--mono); font-size: 0.9em; color: var(--on-ink-soft); }
.doc__table a { color: var(--hibiscus); }

.doc .beat__lede a { color: var(--hibiscus); }

/* ===== motion bar =====================================================
   Shown only to visitors whose OS asks for reduced motion, so they can opt
   back in. See js/motion.js for why this exists. */
.motionbar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 130;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem var(--pad-x);
  background: var(--sun);
  color: #000;
  font-family: var(--mono);
  font-size: var(--step--1);
}

.motionbar__btn {
  padding: 0.4rem 0.9rem;
  border: 0;
  border-radius: 100px;
  background: #000;
  color: var(--sun);
  font-size: inherit;
  font-weight: 600;
  cursor: pointer;
}

/* ===== entrance state =================================================
   JS adds .is-ready to <html> once GSAP has taken over. Until then these
   elements sit hidden. The no-js / no-motion path never adds it, so the
   :not() guard is what makes the content visible again. */
html:not(.is-ready) .reveal { opacity: 1; }

.is-ready .reveal { opacity: 0; }

/* ===== reduced motion =================================================
   Tamed, not switched off: fades and short moves survive, continuous and
   scroll-scrubbed motion does not.

   Both rule sets below say the same thing, and the guards matter:

   .m-tame        set by js/motion.js. This is the authority, because it is the
                  same decision the scripts act on.
   media query    the no-JS fallback, scoped to html:not(.m-full) so that an
                  explicit opt-in to full motion — ?motion=full, or the button
                  on the notice bar — is not silently overruled by the OS. That
                  mismatch is what breaks the parallax bands: the script moves
                  an image whose overflow the stylesheet has already removed. */
.m-tame { scroll-behavior: auto; }

.m-tame *, .m-tame *::before, .m-tame *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.16s !important;
}

.m-tame .card:hover,
.m-tame .btn:hover { transform: none; }
.m-tame .bleed img { height: 100%; }

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

  html:not(.m-full) *,
  html:not(.m-full) *::before,
  html:not(.m-full) *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.16s !important;
  }

  html:not(.m-full) .card:hover,
  html:not(.m-full) .btn:hover { transform: none; }
  html:not(.m-full) .bleed img { height: 100%; }
}

/* ===== responsive ====================================================== */
@media (max-width: 900px) {
  /* No hamburger: the footer carries the same five links, and the page is one
     scroll. A drawer here would be a menu that hides five anchors. */
  .nav__links { display: none; }
  .nav__clock { margin-left: auto; }
}

@media (max-width: 620px) {
  .hero { min-height: 92svh; }
  .hero__head { max-width: none; }
  .stack { grid-template-columns: 1fr; }
  /* min-height goes back to auto so it cannot fight the ratio set here. */
  .stack__f--tall { grid-row: auto; aspect-ratio: 4 / 3; min-height: 0; }
  .stack__f--wide { grid-column: auto; }
  .stamp { flex-wrap: wrap; }
  .stamp__track { max-width: 120px; }
  .svc--flip .svc__media { order: 0; }
}
