/* coming-soon.css — Remi pre-launch v2 (LinkedIn-first foreground).
 *
 * One fixed viewport. No scroll. Three layers:
 *   1. Interactive warm-field canvas (z 1) — a grid of warm motes that
 *      brighten / lift on cursor proximity. Background atmosphere only.
 *   2. Soft vignette over paper (z 2).
 *   3. Foreground (z 10) — eyebrow + smaller "Remi — Coming soon" statement
 *      sitting above the dominant LinkedIn tile block (4 tiles, names below).
 *
 * Hard rules:
 *   - The page MUST NOT scroll. body { overflow: hidden; height: 100svh }.
 *   - LCP candidate = the LinkedIn tile row (.tile-row). Paints at first
 *     paint — NO opacity gate, NO reveal animation, NO transform that hides
 *     it from initial layout.
 *   - Compositor-friendly motion only (transform, opacity).
 *   - prefers-reduced-motion: reduce — canvas hidden (CSS + JS gate);
 *     cursor glow hidden; tile lift collapses to color transition.
 *   - pointer:coarse — no cursor glow, no magnetic; canvas falls back to
 *     a calm static drift (handled in JS).
 *   - No third-party CSS. Only Google Fonts allowed by the strict CSP.
 *   - Color: cream, warm-amber, deep-green, tan family ONLY. No LinkedIn
 *     blue, no neon, no purple/pink (per CONTEXT.md banned list).
 */

/* ---------- Tokens (warm Signal Quarry, cream paper) ---------- */
:root {
  /* Palette — same warm cream lineage as the Signal Quarry track. */
  --paper:        #f3eedf;
  --paper-2:      #ede6d0;
  --paper-3:      #e7dec3;
  --ink:          #1f1e1b;
  --ink-2:        #3f3d37;
  --ink-soft:     #76726a;
  --ink-faint:    #b3aea0;
  --green:        #2d4a3a;
  --green-2:      #1f3729;
  --tan:          #b8895a;
  --tan-2:        #a06f3f;

  /* Type — the v2 statement is smaller than v1 (the tile block is now the
     dominant visual element). Cap at 18vh so short landscape phones stay
     safe and the tile row is never pushed below the fold. */
  --type-eyebrow:   12.5px;
  --type-statement: min(
    clamp(2rem, 5.4vw, 3.5rem),
    11vh
  );
  --type-block-heading: clamp(13px, 1.05vw, 14.5px);
  --type-tile-name:     clamp(14px, 1.15vw, 16px);
  --type-tile-role:     clamp(11px, 0.85vw, 12.5px);

  /* Spacing rhythm. */
  --space-edge:     clamp(1.25rem, 4vw, 3rem);
  --space-stack-lg: clamp(20px, 3.6vh, 40px);
  --space-stack-md: clamp(12px, 1.8vh, 20px);

  /* Tile sizing — square footprint, grows with viewport but caps so the row
     never exceeds the safe single-viewport budget. */
  --tile-size:      clamp(76px, 9.2vw, 112px);
  --tile-radius:    14px;
  --tile-gap:       clamp(14px, 2vw, 28px);

  /* Motion timing. */
  --ease-out-expo:  cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---------- Reset + paper ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
html, body {
  /* Single viewport. No scroll on any axis. */
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}
a { color: inherit; text-decoration: none; }

/* ---------- Interactive warm-field canvas ---------- */
/* Background atmosphere. The cursor reshapes a grid of warm motes (brighter +
   larger when the pointer is near). The canvas itself never receives pointer
   events — it's purely visual. */
#warm-field {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  /* The canvas paints semi-transparent warm-amber motes onto cream; multiply
     gives the deepening "candlelit paper" feel that matches the cursor glow. */
  mix-blend-mode: multiply;
  opacity: 0.92;
}

@media (prefers-reduced-motion: reduce) {
  #warm-field {
    /* Reduced motion: hide entirely — paint just stays cream paper. */
    display: none;
  }
}

/* ---------- Vignette over paper (soft warm darkening at edges) ---------- */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  background: radial-gradient(
    ellipse 92vw 96vh at 50% 50%,
    transparent 0%,
    transparent 55%,
    color-mix(in oklch, var(--paper-3) 40%, transparent) 100%
  );
}

/* ---------- The page (single full-viewport flex column) ---------- */
.page {
  position: relative;
  z-index: 10;
  /* 100svh keeps mobile address-bar collapse from triggering layout shift. */
  height: 100svh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: clamp(1.5rem, 4vh, 3rem) var(--space-edge);
  gap: var(--space-stack-lg);
}

/* ---------- Lead block (eyebrow + smaller statement) ---------- */
.lead {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-stack-md);
  max-width: 32ch;
  text-align: center;
}

.eyebrow {
  margin: 0;
  font-family: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
  font-size: var(--type-eyebrow);
  font-weight: 500;
  letter-spacing: 0.18em;
  color: var(--ink-soft);
  text-transform: uppercase;
}
.eyebrow span {
  display: inline-block;
  margin: 0 0.4em;
  opacity: 0.7;
  color: var(--tan-2);
}

.statement {
  margin: 0;
  font-family: 'Instrument Serif', serif;
  font-weight: 400;
  font-style: normal;
  font-size: var(--type-statement);
  line-height: 1.05;
  letter-spacing: -0.018em;
  text-align: center;
  color: var(--ink);
  /* The statement is editorial seasoning above the LinkedIn block — it must
     paint immediately, but it is no longer the LCP candidate (the tile row is
     larger). No reveal animation; no opacity gate. */
}
.statement .statement-name {
  color: var(--green);
  font-style: italic;
}
.statement .statement-divider {
  color: var(--ink-soft);
  font-style: normal;
  white-space: nowrap;
  /* Em dash sits slightly tighter to balance the italic + roman pair. */
  margin: 0 0.05em;
}
.statement .statement-tail {
  color: var(--ink);
  font-style: normal;
}

/* ---------- LinkedIn block (the dominant foreground) ---------- */
.linkedin-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-stack-md);
  /* Cap so on ultra-wide screens the row still reads as a contained editorial
     block, not a stretched billboard. */
  max-width: min(720px, calc(100vw - 2 * var(--space-edge)));
  width: 100%;
}

.block-heading {
  /* Small section label — the tiles are the louder voice. The page <h1> still
     lives here so the document outline is correct, but the visual scale is
     editorial-quiet (the tile row is the LCP candidate, not this h1). */
  margin: 0;
  font-family: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
  font-size: var(--type-block-heading);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: center;
}

.tile-row {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;
  gap: var(--tile-gap);
  width: 100%;
}

.tile-cell {
  display: inline-flex;
}

/* The tile itself — square deep-green block (the "in" glyph in cream) + name
   block below. Compositor-friendly hover lift. */
.tile {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 6px;
  border-radius: calc(var(--tile-radius) + 6px);
  outline: none;
  /* Lift / shadow handled with transform + filter — no layout-bound props. */
  transform: translate3d(0, 0, 0);
  transition:
    transform 360ms var(--ease-out-expo),
    filter 360ms var(--ease-out-expo);
  will-change: transform;
}

.tile-square {
  /* The dominant visual mark. Deep-green tile with the cream "in" glyph.
     Brand-aligned, NOT LinkedIn blue (#0a66c2). */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tile-size);
  height: var(--tile-size);
  background: var(--green);
  color: var(--paper);
  border-radius: var(--tile-radius);
  /* A subtle inner highlight + warm drop shadow read as "intentionally
     printed onto the paper", not floating UI. */
  box-shadow:
    inset 0 1px 0 color-mix(in oklch, var(--paper) 14%, transparent),
    0 1px 1px color-mix(in oklch, var(--ink) 6%, transparent),
    0 8px 24px -10px color-mix(in oklch, var(--green-2) 70%, transparent);
  transition:
    background 240ms var(--ease-out-expo),
    box-shadow 360ms var(--ease-out-expo);
}

.tile-glyph {
  width: 56%;
  height: 56%;
  display: block;
}

.tile-meta {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.tile-name {
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  font-size: var(--type-tile-name);
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink);
  text-align: center;
  white-space: nowrap;
}

/* The company name renders in Instrument Serif italic so users immediately
   read it as a brand mark, not a person. */
.tile-name--company {
  font-family: 'Instrument Serif', serif;
  font-style: italic;
  font-weight: 400;
  font-size: calc(var(--type-tile-name) * 1.18);
  letter-spacing: -0.01em;
  color: var(--green);
}

.tile-role {
  font-family: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
  font-size: var(--type-tile-role);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Hover / focus — lift the tile slightly and deepen the shadow. JS magnetic
   stacks on top of this base transform via the lift CSS custom property. */
.tile:hover .tile-square,
.tile:focus-visible .tile-square {
  background: var(--green-2);
  box-shadow:
    inset 0 1px 0 color-mix(in oklch, var(--paper) 18%, transparent),
    0 1px 1px color-mix(in oklch, var(--ink) 8%, transparent),
    0 18px 36px -12px color-mix(in oklch, var(--green-2) 80%, transparent);
}
.tile:hover {
  transform: translate3d(0, -3px, 0);
}

.tile:focus-visible {
  /* Cream paper + the warm cursor glow can wash out the UA focus ring.
     This outline is brand-aligned and clearly visible against both paper
     and the warm halo. */
  outline: 2px solid var(--green);
  outline-offset: 4px;
}

/* ---------- Reduced motion — calm everything ---------- */
@media (prefers-reduced-motion: reduce) {
  .tile,
  .tile-square {
    transition: none !important;
    transform: none !important;
  }
  .tile:hover {
    transform: none !important;
  }
}

/* ---------- Narrow viewports ---------- */
/* At 768 and below the row wraps to two-by-two naturally. We tune the
   spacing so the four-tile column doesn't crowd the statement above. */
@media (max-width: 720px) {
  :root {
    --tile-size: clamp(72px, 22vw, 100px);
    --tile-gap:  clamp(12px, 3.5vw, 22px);
  }
  .linkedin-block {
    max-width: min(440px, calc(100vw - 2 * var(--space-edge)));
  }
  .tile-row {
    /* 2 columns at narrow widths. We do this with explicit grid so the four
       cells lay out cleanly without flex-wrap orphan rows. */
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    justify-items: center;
    row-gap: var(--tile-gap);
    column-gap: var(--tile-gap);
  }
}

@media (max-width: 380px) {
  :root {
    --type-statement: min(
      clamp(1.65rem, 8.5vw, 2.5rem),
      11vh
    );
    --tile-size: clamp(64px, 26vw, 86px);
  }
  .lead {
    max-width: 22ch;
  }
}

/* ---------- Very short viewports (landscape phones) ---------- */
@media (max-height: 520px) {
  :root {
    --type-statement: min(
      clamp(1.5rem, 4.5vw, 2.25rem),
      14vh
    );
    --tile-size: clamp(58px, 12vh, 80px);
    --space-stack-lg: clamp(10px, 2vh, 18px);
    --space-stack-md: clamp(6px, 1vh, 12px);
  }
  .page {
    padding-top: clamp(0.8rem, 2vh, 1.2rem);
    padding-bottom: clamp(0.8rem, 2vh, 1.2rem);
  }
  .tile-row {
    /* On short landscape, force a single horizontal row so the page doesn't
       stack vertically past the fold. */
    display: flex;
    flex-wrap: nowrap;
  }
  .tile {
    gap: 6px;
  }
}
