/* Hallmark · pre-emit critique: P5 H5 E5 S5 R5 V5
 * Hallmark · macrostructure: Marquee Hero (scroll-driven) · studied: yes
 * theme: studied-DNA · DNA-source: url
 * source-url: https://styles.refero.design/style/dd8b7191-a992-4dab-88f8-f67e8819b461
 * observed-fonts: Changa One 400 + Arial 400
 * observed-canvas: #ffe600 · observed-ink: #333333 · observed-focal: #007fff
 * rhythm: unknown (URL mode)
 * nav: Top Centered (DNA component) · footer: Ft1 Mast-headed
 * tone: playful-utilitarian · genre: playful
 *
 * The illustration IS the interface: one spaghetti strand of exactly
 * 1,000,000 units runs the length of the page. Nothing here is a card.
 */

@import url("tokens.css");

/* ---------------------------------------------------------------- reset */

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

html,
body {
  overflow-x: clip;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  background: var(--color-canvas);
}

body {
  /* the yellow is the canvas, not a surface sitting on a white page */
  background: var(--color-canvas);
  color: var(--color-ink);
  font-family: var(--font-chrome);
  font-size: var(--text-body);
  line-height: var(--lh-body);
}

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

a {
  color: inherit;
}

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

:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 3px;
  transition: none;
}

/* --------------------------------------------------------- display type */

h1,
h2,
h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-style: normal;
  margin: 0;
  overflow-wrap: anywhere;
  min-width: 0;
  /* line-height compresses as size grows: display lines overlap on purpose
   * and read printed rather than spaced. That stacking is the signature. */
  font-size: var(--text-display);
  line-height: var(--lh-display);
}

h2 {
  font-size: var(--text-heading);
  line-height: var(--lh-heading);
}

h3 {
  font-size: var(--text-heading-sm);
  line-height: var(--lh-heading-sm);
}

p {
  margin: 0 0 var(--space-sm);
  max-width: 54ch;
}

.sub {
  font-family: var(--font-display);
  font-size: var(--text-subheading);
  line-height: var(--lh-subheading);
}

.cap {
  font-size: var(--text-caption);
  line-height: var(--lh-caption);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0;
}

.tnum {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.shell {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ------------------------------------------------------------------ nav */

/* Overlays the first scene rather than pushing it down: a nav in flow makes
 * the sticky stage taller than the viewport and the odometer falls off. */
.nav {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 4;
  /* The links are the same #333333 as the strand. Without a band of canvas
   * behind them the strand swallows whichever word it happens to cross. */
  background: var(--color-canvas);
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  padding-block: var(--space-xs);
}

.nav a {
  font-family: var(--font-chrome);
  font-size: var(--text-body);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--color-ink);
  padding: var(--space-xs) var(--space-sm);
  white-space: nowrap;
  border-bottom: var(--rule) solid transparent;
}

/* the only interactive signal in the system: a short rule under the word */
.nav a:hover,
.nav a.is-on {
  border-bottom-color: var(--color-ink);
}

/* --------------------------------------------- the stretch (the scene) */

.stretch {
  position: relative;
  /* how long the million feels. Every screen of scroll is more spaghetti. */
  height: 1100vh;
}

.stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: clip;
}

#noodle {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  user-select: none;
}

/* A drag on a touch screen has to stay a scroll, so the grab handle only
 * shows up where there is a real pointer to grab with. */
@media (pointer: fine) {
  #noodle {
    cursor: grab;
  }
}

.fine-only,
.coarse-only {
  display: none;
}

@media (pointer: fine) {
  .fine-only {
    display: block;
  }
}

@media (pointer: coarse) {
  .coarse-only {
    display: block;
  }
}

.beat {
  position: absolute;
  z-index: 2;
  left: var(--gutter);
  right: var(--gutter);
  display: none;
}

/* hard cut between beats. No fade, no drift: this DNA cuts, it does not blend */
.beat.is-on {
  display: block;
}

.beat--top {
  top: clamp(40px, 10vh, 110px);
}

.beat--low {
  bottom: clamp(84px, 17vh, 180px);
}

.beat h1,
.beat h2 {
  max-width: 11ch;
}

.beat p {
  max-width: 34ch;
  margin-top: var(--space-xs);
}

/* Side is decided at runtime by where the strand actually is, not authored
 * per beat: the strand wanders, so a fixed side collides sooner or later. */
.stage .beat {
  text-align: left;
  max-width: min(46%, 30rem);
  right: auto;
}

.stage.strand-right .beat {
  text-align: left;
  left: var(--gutter);
}

.stage:not(.strand-right) .beat {
  text-align: right;
  left: auto;
  right: var(--gutter);
}

.stage:not(.strand-right) .beat h1,
.stage:not(.strand-right) .beat h2,
.stage:not(.strand-right) .beat p {
  margin-left: auto;
}

/* the odometer: the length gets felt, not claimed */
.hud {
  position: absolute;
  z-index: 3;
  left: 0;
  right: 0;
  bottom: 0;
  padding: var(--space-xs) var(--gutter);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-sm);
  border-top: var(--rule) solid var(--color-ink);
  background: var(--color-canvas);
}

.hud b {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-heading-sm);
  line-height: 1;
}

.hud__mark {
  flex: 1 1 auto;
  text-align: center;
  min-width: 0;
}

.hud__slurp {
  font-family: var(--font-chrome);
  font-size: var(--text-caption);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-ink);
  background: none;
  border: 0;
  border-bottom: var(--rule) solid var(--color-ink);
  border-radius: 0;
  padding: 0 0 2px;
  cursor: pointer;
  white-space: nowrap;
}

.hud__slurp:hover {
  border-bottom-color: transparent;
}

/* -------------------------------------------------------- generic scene */

.scene {
  position: relative;
  padding-block: var(--space-lg);
  background: var(--color-canvas);
}

.scene--tight {
  padding-block: var(--space-md);
}

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-md);
  align-items: start;
}

.row--center {
  justify-content: center;
}

.stack > * + * {
  margin-top: var(--space-sm);
}

/* ------------------------------------------------------------ the globe */
/* The one radius in the system. A sphere carved out of the canvas, never a
 * card. White display text lies directly on it, no shadow, no stroke. */

.globe {
  border-radius: var(--radius-globe);
  background: var(--color-azure);
  color: var(--color-white);
  aspect-ratio: 1;
  width: min(86vw, 520px);
  margin-inline: auto;
  display: grid;
  place-content: center;
  text-align: center;
  padding: 12%;
}

/* White on #007fff measures 3.83:1 — below AA for normal text, fine for
 * large. So everything inside the globe is set at large-text size rather
 * than darkening a colour the DNA fixes. */
.globe h2 {
  font-size: var(--text-globe);
  line-height: var(--lh-heading-sm);
}

.globe .sub {
  font-size: var(--text-globe-sub);
  line-height: var(--lh-heading-sm);
  margin-top: var(--space-xs);
}

.globe h2,
.globe p {
  color: var(--color-white);
  margin-inline: auto;
}

.arrival {
  display: grid;
  place-items: center;
  gap: var(--space-md);
}

.arrival figure {
  margin: 0;
  width: min(70vw, 320px);
}

/* --------------------------------------------------------------- chrome */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-chrome);
  font-size: var(--text-body);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--color-ink);
  background: none;
  border: var(--rule) solid var(--color-ink);
  border-radius: var(--radius);
  padding: var(--space-xs) var(--space-sm);
  cursor: pointer;
  white-space: nowrap;
  transition:
    background var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}

.btn:hover:not(:disabled),
.btn.is-hover {
  background: var(--color-ink);
  color: var(--color-canvas);
}

.btn:active:not(:disabled) {
  transform: translateY(2px);
}

.btn:disabled,
.btn[aria-disabled="true"],
.btn--dead {
  border-style: dashed;
  cursor: not-allowed;
}

.btn--dead {
  cursor: default;
}

.btn--dead:hover,
.btn:disabled:hover {
  background: none;
  color: var(--color-ink);
}

.row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: center;
}

.ca {
  font-family: var(--font-chrome);
  font-size: var(--text-body);
  word-break: break-all;
  border-bottom: var(--rule) solid var(--color-ink);
  padding-bottom: var(--space-2xs);
  margin-bottom: var(--space-xs);
  max-width: 46ch;
}

/* ------------------------------------------------------------- the tools */

.drop {
  border: var(--rule) dashed var(--color-ink);
  padding: var(--space-md) var(--space-sm);
  text-align: center;
}

.drop.is-over {
  border-style: solid;
  background: var(--color-ink);
  color: var(--color-canvas);
}

.drop.is-over .btn {
  border-color: var(--color-canvas);
  color: var(--color-canvas);
}

.readout {
  margin-top: var(--space-sm);
}

.readout .line {
  display: grid;
  grid-template-columns: minmax(0, 9ch) minmax(0, 1fr) auto;
  gap: var(--space-xs);
  align-items: baseline;
  padding-block: var(--space-xs);
  border-top: var(--rule) solid var(--color-ink);
}

.verdict {
  font-family: var(--font-display);
  font-size: var(--text-caption);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.verdict[data-ok="no"] {
  color: var(--color-coral);
}

.line .name {
  overflow-wrap: anywhere;
  min-width: 0;
}

.line .num {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.slate {
  border: var(--rule) solid var(--color-ink);
  aspect-ratio: 1;
  width: 100%;
  touch-action: none;
  cursor: crosshair;
}

.slate.is-done {
  cursor: not-allowed;
}

.gauge {
  border: var(--rule) solid var(--color-ink);
  height: 18px;
  display: flex;
  margin-block: var(--space-xs);
}

.gauge i {
  display: block;
  background: var(--color-ink);
  width: 0;
  transition: width var(--dur-fast) linear;
}

.tally {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: var(--space-xs);
}

.tally b {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-heading-sm);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.note {
  border-left: var(--rule) solid var(--color-ink);
  padding-left: var(--space-xs);
}

.note p:last-child {
  margin-bottom: 0;
}

pre {
  border: var(--rule) solid var(--color-ink);
  padding: var(--space-xs);
  overflow-x: auto;
  font-family: var(--font-chrome);
  font-size: var(--text-body);
  margin: 0;
}

/* --------------------------------------------------------------- footer */

.mast {
  border-top: var(--rule) solid var(--color-ink);
  padding-block: var(--space-md);
  background: var(--color-canvas);
}

.mast .wordmark {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-heading);
  line-height: var(--lh-heading);
  margin: 0 0 var(--space-xs);
}

.mast .tagline {
  font-family: var(--font-display);
  font-size: var(--text-subheading);
  line-height: var(--lh-subheading);
  max-width: 32ch;
}

.colophon {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-sm);
  border-top: var(--rule) solid var(--color-ink);
  margin-top: var(--space-sm);
  padding-top: var(--space-xs);
  font-size: var(--text-caption);
}

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

/* ----------------------------------------------------------- responsive */

@media (max-width: 720px) {
  .split {
    grid-template-columns: minmax(0, 1fr);
  }
  /* No room to dodge on a phone: the strand fills the frame, so the copy
     goes back to one column and simply sits over it at the top. */
  .stage .beat,
  .stage.strand-right .beat,
  .stage:not(.strand-right) .beat {
    max-width: none;
    text-align: left;
    left: var(--gutter);
    right: var(--gutter);
  }
  .stage:not(.strand-right) .beat h1,
  .stage:not(.strand-right) .beat h2,
  .stage:not(.strand-right) .beat p {
    margin-left: 0;
  }
  .beat h1,
  .beat h2 {
    max-width: none;
  }
  /* the nav overlays the first scene and wraps to two rows here, so the
     * opening beat has to start below it */
  .beat--top {
    top: 96px;
  }
  .hud__mark {
    order: 3;
    flex-basis: 100%;
    text-align: left;
  }
  .hud {
    flex-wrap: wrap;
    gap: var(--space-2xs) var(--space-sm);
  }
  .readout .line {
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .readout .verdict {
    grid-column: 1 / -1;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation: none !important;
  }
}
