/* ============================================================
   TUMMI — Zeegloed v5.1 · THE BLOOM & GLASS LAYER
   (components-blooms.css · SPEC-DELTA §2, §3, §4, §7)

   "Het warme licht komt van achter het glas, nooit op de
   letters." Vivid blooms are surfaces you place a chip ON,
   never print on. Hero blooms carry a real #0C1428 void core
   so cream metadata stays 15.85:1. Health data NEVER rides a
   bloom — that fence lives in the FENCE block (§4) and in the
   role comments below. Every animation freezes under
   prefers-reduced-motion. All colour comes from tokens.css.
   ============================================================ */

/* ============================================================
   §2a · VIVID BLOOMS — .bloomcard + .bloomcard--vivid-*
   Opaque, crisp, unblurred, no grain. Feature surfaces only:
   website feature/flip cards, deck accent cards, empty-state
   art, onboarding celebration. NEVER app data tiles, meters,
   weekring, symptom scale, or any health readout.
   ============================================================ */
.bloomcard {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--r-lg);
  padding: var(--s-5);
  color: var(--ink);
  box-shadow: var(--shadow-md);
}
.bloomcard--vivid-gold    { background: var(--bloom-vivid-gold); }
.bloomcard--vivid-amber   { background: var(--bloom-vivid-amber); }
.bloomcard--vivid-apricot { background: var(--bloom-vivid-apricot); }
.bloomcard--vivid-coral   { background: var(--bloom-vivid-coral); }
.bloomcard--vivid-rose    { background: var(--bloom-vivid-rose); }
.bloomcard--vivid-sage    { background: var(--bloom-vivid-sage); }
.bloomcard--vivid-sky     { background: var(--bloom-vivid-sky); }

/* ---- THE --vivid-textbed SCRIM ----
   NAKED-CREAM BAN: the luminous end of a vivid bloom FAILS AA
   for naked cream — cream on raw coral = 2.68, on rose = 2.66
   (both < 4.5). So AA-required text NEVER prints straight on a
   vivid bloom; it rides the universal dark bed. .bc-text is the
   text run; its ::after paints the scrim behind it (z-index -1
   inside the isolated box), lifting cream to >=5.48 on every
   vivid hue. */
.bloomcard .bc-text {
  position: relative;
  isolation: isolate;
  display: inline-block;
  max-width: 100%;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  color: var(--ink-inverse);
}
.bloomcard .bc-text::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--vivid-textbed);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

/* ============================================================
   §2b · HERO BLOOMS — .tile--hero-* + breathing glow ::before
   Near-void core (the one real #0C1428) blooming from the rim.
   Cream --ink-inverse = 15.85:1 on the shared core. ONE hero
   bloom per screen. NEVER behind a meter, weekring, symptom
   word, or any health readout.
   ============================================================ */
.tile--hero-coral,
.tile--hero-sky,
.tile--hero-rose,
.tile--hero-sage {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--r-lg);
  padding: var(--s-6);
  color: var(--ink-inverse);
  box-shadow: var(--shadow-lg);
}
.tile--hero-coral { background: var(--bloom-hero-coral); }
.tile--hero-sky   { background: var(--bloom-hero-sky); }
.tile--hero-rose  { background: var(--bloom-hero-rose); }
.tile--hero-sage  { background: var(--bloom-hero-sage); }

.tile--hero-coral::before,
.tile--hero-sky::before,
.tile--hero-rose::before,
.tile--hero-sage::before {
  content: "";
  position: absolute;
  inset: -6%;
  z-index: 0;
  pointer-events: none;
  animation: heroBreath var(--d-hero-breath) ease alternate infinite;
}
.tile--hero-coral::before { background: var(--glow-hero-coral); }
.tile--hero-sky::before   { background: var(--glow-hero-sky); }
.tile--hero-rose::before  { background: var(--glow-hero-rose); }
.tile--hero-sage::before  { background: var(--glow-hero-sage); }

.tile--hero-coral > *,
.tile--hero-sky > *,
.tile--hero-rose > *,
.tile--hero-sage > * { position: relative; z-index: 1; }

@keyframes heroBreath {
  from { transform: scale(1);    opacity: .85; }
  to   { transform: scale(1.04); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .tile--hero-coral::before,
  .tile--hero-sky::before,
  .tile--hero-rose::before,
  .tile--hero-sage::before {
    animation: none;
    transform: none;
    opacity: .92;
  }
}

/* ============================================================
   §3 · LIQUID GLASS — .glass-liquid
   Warmth + glow come from the BACKDROP FILTER, never a white
   veil. Cream text is only guaranteed over DARK-reading
   backdrops (glass over the void = 13.23:1). Over a LIGHT vivid
   bloom the backdrop brightens — put such text on .bc-text or
   flip to dark --ink. Light + dark handled entirely by tokens.
   ============================================================ */
.glass-liquid {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--r-lg);
  padding: 22px;
  color: var(--ink-inverse);
  text-shadow: 0 1px 11px rgba(10,6,2,.55);
  background: var(--glass-liquid-veil);
  border: 1px solid var(--glass-liquid-brd);
  -webkit-backdrop-filter: var(--glass-liquid-blur);
  backdrop-filter: var(--glass-liquid-blur);
  box-shadow: var(--glass-liquid-shadow);
}
[data-theme="dark"] .glass-liquid { text-shadow: 0 1px 12px rgba(0,0,0,.6); }
.glass-liquid::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  border-radius: inherit;
  background: var(--glass-liquid-sheen);
}
.glass-liquid > * { position: relative; z-index: 1; }

/* ============================================================
   §4 · THE DOTTED NUMERAL — .dotnum + sizes sm/md/lg/xl
   The ONE sanctioned background-clip:text use in the system:
   a SINGLE cream dot texture, never a hue ramp (gradient-text
   law holds). Read the FENCE below before placing one.
   ============================================================ */
.dotnum {
  font-family: var(--font-num, var(--font-mono));
  font-weight: 700;
  line-height: .86;
  letter-spacing: .02em;
  color: transparent;
  background-image: radial-gradient(var(--dot-ink) 40%, transparent 43%);
  background-size: var(--dot-grid) var(--dot-grid);
  -webkit-background-clip: text;
  background-clip: text;
  filter: drop-shadow(0 0 6px var(--dot-halo));
}
.dotnum.sm { font-size: 44px;  --dot-grid: 3.4px; }
.dotnum.md { font-size: 62px;  --dot-grid: 4.6px; }
.dotnum.lg { font-size: 84px;  --dot-grid: 6px; }
.dotnum.xl { font-size: 112px; --dot-grid: 7px; }

/* +--------------------------------------------------------+
   |  THE FENCE — Tummi law, stricter than Eyro.            |
   |                                                        |
   |  1. Mono METADATA only, never a score — a day count,   |
   |     unit, streak length, timestamp. A number that is   |
   |     not a judgment.                                    |
   |  2. ONLY on hero-bloom cores (#0C1428, cream 15.85:1). |
   |     NEVER on a vivid bloom (naked cream fails AA), a    |
   |     meter, weekring, factor row, symptom scale, KPI,   |
   |     table, or any health/clinical readout. On a vivid  |
   |     bloom it MUST ride a .bc-text scrim.               |
   |  3. The fill is a single cream dot — NEVER a hue       |
   |     gradient. Single-hue dot TEXTURE, not a value ramp.|
   |                                                        |
   |  Scores + /100 belong to .statnum (plain solid ink),   |
   |  not here. Eyro's chrome-gradient .chromenum is DROPPED.|
   +--------------------------------------------------------+ */

/* ============================================================
   §7/82 · THE STACKED-DECK CAROUSEL
   .deck / .deck-stage / .deck-ctl / .deck-dot
   Hero-bloom cards stacked in one grid cell; CSS-only depth via
   nth-child translate/scale/opacity; the promoted card carries
   .is-front. .55s settle transition; reduced-motion = instant.
   ============================================================ */
.deck {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}
.deck-stage {
  position: relative;
  display: grid;
  min-height: 320px;
}
.deck-stage > * {
  grid-area: 1 / 1;
  transition: transform .55s var(--ease-settle), opacity .55s var(--ease-settle);
  will-change: transform, opacity;
}
.deck-stage > *:nth-child(1) { transform: translateY(0)    scale(1);   opacity: 1;  z-index: 3; }
.deck-stage > *:nth-child(2) { transform: translateY(18px) scale(.94); opacity: .6; z-index: 2; }
.deck-stage > *:nth-child(3) { transform: translateY(34px) scale(.88); opacity: .3; z-index: 1; }
.deck-stage > .is-front      { transform: translateY(0)    scale(1);   opacity: 1;  z-index: 4; }

.deck-controls { display: inline-flex; align-items: center; gap: var(--s-3); }
.deck-ctl {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-pill);
  border: 1px solid var(--hairline-strong);
  background: var(--raise);
  color: var(--ink);
  cursor: pointer;
  transition: transform var(--d-state) var(--ease-settle),
              box-shadow var(--d-state) var(--ease-settle);
}
.deck-ctl:hover  { transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.deck-ctl:active { transform: translateY(0) scale(.96); }
.deck-dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--hairline-strong);
  cursor: pointer;
  transition: transform var(--d-state) var(--ease-settle),
              background var(--d-state) var(--ease-settle);
}
.deck-dot.is-active { background: var(--coral); transform: scale(1.3); }
@media (prefers-reduced-motion: reduce) {
  .deck-stage > * { transition: opacity 150ms var(--ease-settle); }
}

/* ============================================================
   §7/83 · .statchip — frosted stat chip for over-bloom clusters
   The sanctioned hero overlap: a light frost placed on a bloom.
   ============================================================ */
.statchip {
  display: inline-flex;
  flex-direction: column;
  gap: var(--s-1);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-md);
  background: rgba(255,252,246,.16);
  -webkit-backdrop-filter: blur(6px) saturate(120%);
  backdrop-filter: blur(6px) saturate(120%);
  border: 1px solid var(--glass-liquid-brd);
  color: var(--ink-inverse);
  text-shadow: 0 1px 8px rgba(10,6,2,.5);
}

/* §7/85 · deck-article helpers (content that rides a hero bloom) */
.hb-eyb {
  font-family: var(--font-mono);
  font-size: var(--t-eyebrow);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-inverse);
  opacity: .82;
}
.hb-big {
  font-family: var(--font-display);
  font-size: var(--t-display);
  line-height: 1.02;
  color: var(--ink-inverse);
}
.hb-figrow { display: flex; flex-wrap: wrap; gap: var(--s-5); }
.hb-fig {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  font-family: var(--font-mono);
  font-size: var(--t-caption);
  color: var(--ink-inverse);
  opacity: .82;
}

/* ============================================================
   §7/71 · FEATURE FLIP-CARDS — .flipcard / .fc-front / .fc-back
   3D flip on hover/focus-within: 180deg + scale 1.09 over
   --d-reveal. front = mono kicker + .dotnum METADATA + label on
   a vivid bloom (the dotnum rides a .bc-text scrim to hold AA,
   per the FENCE); back = solid --card prose panel. Reduced
   motion = opacity crossfade, no 3D.
   ============================================================ */
.flipcard {
  position: relative;
  perspective: 1200px;
  min-height: 260px;
  border-radius: var(--r-lg);
}
.flipcard-inner {
  position: relative;
  width: 100%;
  min-height: inherit;
  transform-style: preserve-3d;
  transition: transform var(--d-reveal) var(--ease-settle);
}
.flipcard:hover .flipcard-inner,
.flipcard:focus-within .flipcard-inner {
  transform: rotateY(180deg) scale(1.09);
}
.fc-front,
.fc-back {
  position: absolute;
  inset: 0;
  overflow: hidden;
  padding: var(--s-5);
  border-radius: inherit;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.fc-front {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  color: var(--ink-inverse);
}
.fc-back {
  transform: rotateY(180deg);
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow-md);
}
.flipcard--vivid-gold    .fc-front { background: var(--bloom-vivid-gold); }
.flipcard--vivid-amber   .fc-front { background: var(--bloom-vivid-amber); }
.flipcard--vivid-apricot .fc-front { background: var(--bloom-vivid-apricot); }
.flipcard--vivid-coral   .fc-front { background: var(--bloom-vivid-coral); }
.flipcard--vivid-rose    .fc-front { background: var(--bloom-vivid-rose); }
.flipcard--vivid-sage    .fc-front { background: var(--bloom-vivid-sage); }
.flipcard--vivid-sky     .fc-front { background: var(--bloom-vivid-sky); }
.fc-kicker {
  font-family: var(--font-mono);
  font-size: var(--t-eyebrow);
  letter-spacing: .16em;
  text-transform: uppercase;
}
@media (prefers-reduced-motion: reduce) {
  .flipcard-inner { transition: none; transform: none; }
  .flipcard:hover .flipcard-inner,
  .flipcard:focus-within .flipcard-inner { transform: none; }
  .fc-back {
    transform: none;
    opacity: 0;
    z-index: 1;
    transition: opacity 150ms var(--ease-settle);
  }
  .fc-front { transition: opacity 150ms var(--ease-settle); }
  .flipcard:hover .fc-back,
  .flipcard:focus-within .fc-back { opacity: 1; }
  .flipcard:hover .fc-front,
  .flipcard:focus-within .fc-front { opacity: 0; }
}

/* ============================================================
   §5/1 · .herofloat / .fl — the voorwoord floating cluster
   Small vivid tiles + one glass pill, absolute offsets, gentle
   drift; reduced-motion holds them still.
   ============================================================ */
.herofloat {
  position: relative;
  min-height: 340px;
}
.fl {
  position: absolute;
  border-radius: var(--r-md);
  box-shadow: var(--shadow-md);
  animation: bloomFloat 6s ease alternate infinite;
}
.fl:nth-child(1) { top: 4%;    left: 2%;   width: 132px; height: 132px; animation-delay: 0s; }
.fl:nth-child(2) { top: 32%;   right: 5%;  width: 108px; height: 108px; animation-delay: -1.6s; }
.fl:nth-child(3) { bottom: 5%; left: 20%;  width: 154px; height: 96px;  animation-delay: -3.2s; }
@keyframes bloomFloat {
  from { transform: translateY(0); }
  to   { transform: translateY(-12px); }
}
@media (prefers-reduced-motion: reduce) {
  .fl { animation: none; transform: none; }
}

/* ============================================================
   §7/67 · .emit — decorative "signal" dot (coral), + §7/34 .halo
   emit: a coral dot with an expanding ring pulse (connect-a-
   tracker signal). halo: STATIC concentric rings; its core may
   carry the demoted --grad-conic as ornament ONLY — never
   behind a value, arc, or numeral.
   ============================================================ */
.emit {
  position: relative;
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: var(--r-pill);
  background: var(--coral);
}
.emit::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--coral);
  opacity: .5;
  animation: emitPulse var(--d-adem) var(--ease-adem) infinite;
}
@keyframes emitPulse {
  from { transform: scale(1);   opacity: .5; }
  to   { transform: scale(2.6); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .emit::after { animation: none; opacity: .35; transform: scale(1.4); }
}
.halo {
  position: relative;
  display: grid;
  place-items: center;
  width: 140px;
  height: 140px;
}
.halo::before,
.halo::after {
  content: "";
  position: absolute;
  border-radius: var(--r-pill);
  border: 1px solid var(--hairline-warm);
}
.halo::before { width: 100%; height: 100%; opacity: .8; }
.halo::after  { width: 62%;  height: 62%; }
.halo-core {
  width: 30%;
  height: 30%;
  border-radius: var(--r-pill);
  background: var(--grad-conic);   /* decorative ornament only */
}

/* ============================================================
   §7/15 · .nest — THE ONE SANCTIONED NESTED OVERLAP
   A plate carrying two overlapping .glass-liquid chips pulled
   together by a negative margin. This is the single place the
   system permits nested surface overlap; everywhere else,
   surfaces sit apart. Sanctioned, deliberate, documented here.
   ============================================================ */
.nest {
  position: relative;
  border-radius: var(--r-lg);
  padding: var(--s-5);
  background: var(--card);
  box-shadow: var(--shadow-md);
}
.nest .glass-liquid + .glass-liquid {
  margin-top: calc(var(--s-5) * -1);   /* the sanctioned overlap */
  margin-left: var(--s-6);
}

/* ============================================================
   §9/93 · .state-gallery — feedback-state grid
   §9/94 · .vangrails — the nieuw / bewaard / hek triptych
   Mono column headers. No error-red alarm anywhere.
   ============================================================ */
.state-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--s-4);
  align-items: start;
}
.vangrails {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-5);
}
.vangrails > * {
  border-radius: var(--r-md);
  padding: var(--s-5);
  background: var(--card);
  border: 1px solid var(--hairline);
  border-top: 3px solid var(--hairline-strong);
}
.vangrails [data-rail="nieuw"]   { border-top-color: var(--sage); }
.vangrails [data-rail="bewaard"] { border-top-color: var(--sky); }
.vangrails [data-rail="hek"]     { border-top-color: var(--coral); }
.vg-head {
  font-family: var(--font-mono);
  font-size: var(--t-eyebrow);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: var(--s-3);
}
@media (max-width: 720px) {
  .vangrails { grid-template-columns: 1fr; }
}
