/* ═══════════════════════════════════════════════════════════════
   OLWYN — one sealed view
   ───────────────────────────────────────────────────────────────
   Night ground, a fog that drifts, a dial of generated guilloché
   keeping real time, and the tracks of Olwen passing behind it.
   Nothing scrolls. The only motion is rotation, drift, and fade.

   1. Tokens   2. Base & frame   3. Ground and fog
   4. The dial 5. Type & corners 6. Tracks and hidden things
   ═══════════════════════════════════════════════════════════════ */


/* ─── 1. Tokens ─────────────────────────────────────────────── */
:root {
  --night:        #0b0d0c;
  --bone:         #e9e4d6;
  --bone-2:       #b9b3a4;
  --bone-3:       #8d887c;

  --brass:        #b3945c;
  --brass-bright: #dcc389;
  --brass-text:   #c4a86d;
  --brass-line:   rgba(179, 148, 92, 0.38);
  --brass-dim:    rgba(179, 148, 92, 0.20);
  --rule:         rgba(179, 148, 92, 0.16);

  --serif: ui-serif, "Iowan Old Style", "Palatino Linotype", Palatino,
           "Book Antiqua", Georgia, "Times New Roman", serif;
  --sans:  ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
           "Helvetica Neue", Arial, sans-serif;

  --t-small: 0.8125rem;
  --gutter:  clamp(1.25rem, 4vw, 3rem);
  --ease:    cubic-bezier(0.22, 0.61, 0.36, 1);
}


/* ─── 2. Base & frame ───────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
  color-scheme: dark;
  height: 100%;
  -webkit-text-size-adjust: 100%;
}

/* one view: a grid of masthead / scene / foot, sealed shut */
body {
  height: 100dvh;
  overflow: hidden;
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: var(--night);
  color: var(--bone);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: inherit; }

::selection { background: var(--brass); color: var(--night); }

:focus-visible {
  outline: 1.5px solid var(--brass-bright);
  outline-offset: 3px;
}

svg { display: block; }

/* the page condenses out of fog — CSS only, works everywhere */
@keyframes appear { from { opacity: 0; } to { opacity: 1; } }

@keyframes emerge {
  from { opacity: 0; filter: blur(18px); }
  55%  { opacity: 1; }
  to   { opacity: 1; filter: blur(0); }
}

.masthead      { animation: appear 1.8s var(--ease) both 0.5s; }
.stage         { animation: emerge 3.4s var(--ease) both; }
.foot          { animation: appear 1.8s var(--ease) both 0.9s; }


/* ─── 3. Ground and fog ─────────────────────────────────────── */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(90% 60% at 50% 0%, #141712 0%, transparent 62%),
    radial-gradient(140% 100% at 50% 100%, #060707 0%, transparent 55%);
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23f)' opacity='0.05'/%3E%3C/svg%3E");
  mix-blend-mode: screen;
}

.masthead, .foot { position: relative; z-index: 5; }
.scene { position: relative; z-index: 1; overflow: hidden; }

/* the fog: two soft banks drifting against each other, above the
   wheel, below the words. Pale, slow, and never still. */
.fog {
  position: absolute;
  inset: -30%;
  z-index: 4;
  pointer-events: none;
  mix-blend-mode: screen;
  filter: blur(28px);
}

.fog--a {
  background:
    radial-gradient(38% 26% at 24% 62%, rgba(196, 206, 192, 0.10), transparent 70%),
    radial-gradient(30% 22% at 70% 34%, rgba(196, 206, 192, 0.075), transparent 70%),
    radial-gradient(26% 20% at 52% 78%, rgba(196, 206, 192, 0.07), transparent 70%);
  animation: drift-a 75s ease-in-out infinite alternate;
}

.fog--b {
  background:
    radial-gradient(34% 24% at 76% 68%, rgba(196, 206, 192, 0.085), transparent 70%),
    radial-gradient(28% 20% at 34% 28%, rgba(196, 206, 192, 0.07), transparent 70%);
  animation: drift-b 105s ease-in-out infinite alternate;
}

@keyframes drift-a {
  from { transform: translate3d(-3.5%, -1.5%, 0); }
  to   { transform: translate3d(3.5%, 2%, 0); }
}

@keyframes drift-b {
  from { transform: translate3d(3%, 2%, 0); }
  to   { transform: translate3d(-3%, -2.5%, 0); }
}

/* the veil: dense on arrival, lifting as the wheel condenses */
.fog--veil {
  z-index: 4;
  filter: blur(34px);
  background:
    radial-gradient(55% 45% at 50% 46%, rgba(196, 206, 192, 0.30), transparent 74%),
    radial-gradient(40% 30% at 30% 60%, rgba(196, 206, 192, 0.20), transparent 70%),
    radial-gradient(40% 30% at 72% 38%, rgba(196, 206, 192, 0.20), transparent 70%);
  animation: veil-lift 4.2s var(--ease) both;
  opacity: 0;
}

@keyframes veil-lift {
  from { opacity: 1; transform: translate3d(0, 0, 0); }
  to   { opacity: 0; transform: translate3d(2%, -2.5%, 0); }
}

/* a still haze that pools at the foot of the scene */
.haze {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background: linear-gradient(to top, rgba(196, 206, 192, 0.05), transparent 34%);
  mix-blend-mode: screen;
}


/* ─── 4. The dial ───────────────────────────────────────────── */
.stage {
  position: relative;
  z-index: 2;
  height: 100%;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: clamp(1.25rem, 3.5vh, 2.5rem);
  padding: 0 var(--gutter);
  text-align: center;
}

.hero__dial {
  position: relative;
  width: min(88vw, 56vh, 36rem);
  aspect-ratio: 1;
}

.hero__dial svg { width: 100%; height: 100%; overflow: visible; }

.hairline { fill: none; stroke: var(--brass-line); stroke-width: 0.8; }
.hairline--dim { stroke: var(--brass-dim); }
.dot { fill: var(--brass-bright); }

.g-turn path {
  fill: none;
  stroke: var(--brass);
  stroke-width: 0.55;
  opacity: 0.34;
}

.g-sec path { opacity: 0.42; }
.g-slow-a path, .g-slow-b path { opacity: 0.26; }

.g-turn .hand { fill: var(--brass-bright); opacity: 0.9; }

.dial__case text { font-family: var(--sans); fill: var(--brass-text); }

.dial__words {
  font-size: 13.5px;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  opacity: 0.6;
}

.dial__cardinals text {
  font-size: 15px;
  letter-spacing: 0.5em;
  text-transform: uppercase;
  opacity: 0.85;
}

#caseTicks line { stroke: var(--brass-line); stroke-width: 1; }

.hero__word {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  pointer-events: none;
}

.hero__name {
  font-family: var(--serif);
  font-size: clamp(1.2rem, 3.2vmin, 1.9rem);
  letter-spacing: 0.5em;
  text-indent: 0.5em;   /* centres against the trailing letter-space */
  color: var(--bone);
}

/* a raking light on the metal, steered by the pointer */
.hero__dial::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.2s var(--ease);
  background: radial-gradient(circle 38% at var(--gx, 50%) var(--gy, 38%),
              rgba(220, 195, 137, 0.10), transparent 70%);
  mix-blend-mode: screen;
}

.hero__dial.is-lit::after { opacity: 1; }

/* the movement: three rings at true clock rates */
.g-turn { transform-box: view-box; transform-origin: center; }

@keyframes turn {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

.js .g-sec  { animation: turn    60s linear infinite; animation-delay: var(--off-s, 0s); }
.js .g-min  { animation: turn  3600s linear infinite; animation-delay: var(--off-m, 0s); }
.js .g-hour { animation: turn 43200s linear infinite; animation-delay: var(--off-h, 0s); }

/* two more wheels, geared the other way — ornament, not clock */
.js .g-slow-a { animation: turn 150s linear infinite reverse; animation-delay: var(--off-a, 0s); }
.js .g-slow-b { animation: turn 340s linear infinite reverse; animation-delay: var(--off-b, 0s); }

/* typing "troi" gives the wheel one slow, full revolution */
.hero__dial svg {
  transition: transform 3.2s var(--ease);
  transform: rotate(calc(var(--troi, 0) * 360deg));
}


/* ─── 5. Type & corners ─────────────────────────────────────── */
.line {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.2rem, 2.6vmin + 0.5rem, 1.9rem);
  letter-spacing: 0.01em;
  color: var(--bone);
  text-wrap: balance;
}

.masthead { padding: clamp(1rem, 2.5vh, 1.75rem) var(--gutter) 0; }

.masthead__id {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
}

.masthead__mark { width: 19px; color: var(--brass-text); }

.masthead__name {
  font-family: var(--serif);
  font-size: 1.0625rem;
  letter-spacing: 0.09em;
}

.foot {
  padding: 0 var(--gutter) clamp(1rem, 2.5vh, 1.75rem);
  text-align: center;
  font-size: var(--t-small);
  color: var(--bone-2);
}

.foot a {
  text-decoration: none;
  letter-spacing: 0.06em;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 1px;
  transition: border-color 0.6s var(--ease);
}

.foot a:hover { border-color: var(--brass-bright); }


/* ─── 6. Tracks and hidden things ───────────────────────────── */

/* Olwen's tracks: white trefoil prints laid one after another on a
   wandering line, passing behind the wheel, fading as they age. */
.tracks {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}

.track {
  position: absolute;
  width: 17px;
  height: 17px;
  fill: var(--bone);
  opacity: 0;
  transition: opacity 1.6s var(--ease);
}

.track.is-set { opacity: var(--o, 0.17); }
.track.is-old { opacity: 0; }

/* type "olwen": your own pointer leaves prints too */
.bloom {
  position: absolute;
  width: 15px;
  height: 15px;
  fill: var(--bone);
  opacity: 0;
  animation: bloom 4.2s var(--ease) forwards;
}

@keyframes bloom {
  10%  { opacity: 0.5; }
  35%  { opacity: 0.38; }
  100% { opacity: 0; }
}

.bloom-field {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 6;
}

/* the name's origin, for anyone who rests on the masthead */
.gloss {
  display: none;
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  font-size: var(--t-small);
  color: var(--bone-3);
  opacity: 0;
  transition: opacity 0.9s var(--ease);
  pointer-events: none;
  max-width: calc(100vw - 2 * var(--gutter));
}

@media (min-width: 48rem) { .gloss { white-space: nowrap; max-width: none; } }

.gloss em { font-family: var(--serif); font-style: italic; color: var(--brass-text); }

@media (hover: hover) and (pointer: fine) { .gloss { display: block; } }

.masthead__id:hover .gloss,
.masthead__id:focus-visible .gloss { opacity: 1; }


/* ─── Reduced motion: the scene holds still ─────────────────── */
@media (prefers-reduced-motion: reduce) {
  .masthead, .stage, .foot { animation: none; }
  .fog--a, .fog--b { animation: none; }
  .fog--veil { animation: none; opacity: 0; }
  .js .g-slow-a, .js .g-slow-b { animation: none; }
  /* rings hold the angle of the moment the page opened; the JS
     sets that static angle so the dial still tells that time */
  .js .g-sec, .js .g-min, .js .g-hour { animation: none; }
  .hero__dial svg { transition: none; }
  .hero__dial::after { transition: none; }
  .track { transition: none; }
  .track.is-set { opacity: calc(var(--o, 0.17) * 0.85); }
}
