/*
 * Hex bloom chrome for sphere-ux.
 * Closed: one black horizon seed at bottom.
 * Open: bloom roots at the seed; Undo · Close · Flag form its keel.
 * Geometry + fold language from /uxperiments/clex.
 */

.hex-bloom {
  /* Bloom primaries (full size). Dock idle is smaller; grows to match when open. */
  --tile-w: 76px;
  --tile-h: 88px;
  --tile-w-dock-idle: 40px;
  --tile-h-dock-idle: 46px;
  --tile-w-dock: var(--tile-w-dock-idle);
  --tile-h-dock: var(--tile-h-dock-idle);
  --dock-rise: 0px;
  --seed-sink: 44px;
  --border-w: 1.5px;
  --hex-clip: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  --hb-ink: var(--text-main, #000);
  --hb-paper: var(--bg-color, #fff);
  --hb-fill: color-mix(in srgb, var(--hb-paper) 94%, var(--hb-ink));
  --hb-fill-hover: color-mix(in srgb, var(--hb-paper) 82%, var(--hb-ink));
  --hb-stroke: color-mix(in srgb, var(--hb-ink) 70%, transparent);
  --hb-center-fill: var(--hb-ink);
  --hb-center-ink: var(--hb-paper);
  --hb-active-fill: var(--hb-ink);
  --hb-active-ink: var(--hb-paper);
  --hb-accent: var(--hb-ink);
  --hb-scrim: color-mix(in srgb, var(--hb-paper) 18%, transparent);
  --rise-y: 0px;
  --rise-ms: 220ms;
  --fold-ms: 180ms;

  position: fixed;
  inset: 0;
  z-index: 55;
  pointer-events: none;
  font-family: "IBM Plex Sans", system-ui, sans-serif;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* Full-screen blur plate — only intercepts when open */
.hex-bloom-scrim {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--hb-scrim);
  -webkit-backdrop-filter: blur(5px) saturate(1.02);
  backdrop-filter: blur(5px) saturate(1.02);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.18s ease, visibility 0.18s;
}
.hex-bloom[data-open="true"] .hex-bloom-scrim {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* Stage fills viewport; origin is the dock menu (bottom). */
.hex-bloom-stage {
  position: absolute;
  inset: 0;
  z-index: 1;
  perspective: 1100px;
  perspective-origin: 50% 100%;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  /* The petal layer rides the dock's grow+lift: --rise-y starts at the
     idle→open seed delta (dockRiseDelta) and animates to 0, so petals stay
     rooted to the seed instead of hovering at final seats while the dock
     catches up underneath. */
  transform: translateY(var(--rise-y, 0px));
  transition: opacity 0.12s ease, visibility 0.12s;
  /* Room for upward fan without clipping south of the dock */
  overflow: visible;
}
.hex-bloom[data-open="true"] .hex-bloom-stage,
.hex-bloom[data-phase="rising"] .hex-bloom-stage,
.hex-bloom[data-phase="falling"] .hex-bloom-stage {
  opacity: 1;
  visibility: visible;
  transition:
    opacity 0.12s ease,
    visibility 0.12s,
    transform var(--rise-ms) cubic-bezier(0.22, 1, 0.3, 1);
}

/* Bottom chrome: Restart · Menu · Help
   Idle: small + low; open: grow to bloom size and lift with the fan. */
.hex-bloom-dock {
  position: absolute;
  left: 50%;
  bottom: max(2px, env(safe-area-inset-bottom));
  transform: translateX(-50%) translateY(var(--dock-rise, 0px));
  z-index: 3;
  display: flex;
  flex-direction: row;
  align-items: flex-end;
  justify-content: center;
  gap: 0;
  width: auto;
  height: auto;
  pointer-events: none;
  opacity: 1;
  transition:
    opacity 0.28s ease,
    transform var(--rise-ms) cubic-bezier(0.22, 1, 0.3, 1);
}
.hex-bloom[data-phase="open"] .hex-bloom-dock {
  /* Lift so the rooted fan has air and matches bloom height language.
     Only while open: on falling the dock rides back down with the stage
     and the folding petals — one settle, not two. */
  --dock-rise: -36px;
  --tile-w-dock: var(--tile-w);
  --tile-h-dock: var(--tile-h);
}
.hex-bloom-dock .hb-hex.is-dock {
  position: relative;
  left: auto;
  top: auto;
  margin: 0;
  flex: 0 0 auto;
  width: var(--tile-w-dock);
  height: var(--tile-h-dock);
  pointer-events: auto;
  transition:
    width var(--rise-ms) cubic-bezier(0.22, 1, 0.3, 1),
    height var(--rise-ms) cubic-bezier(0.22, 1, 0.3, 1),
    background 0.2s ease,
    color 0.2s ease,
    filter 0.2s ease,
    opacity 0.2s ease;
}
.hex-bloom-dock .is-dock-menu,
.hex-bloom-dock .is-dock-side {
  width: var(--tile-w-dock);
  height: var(--tile-h-dock);
  opacity: 1;
}
/* ?dock=center: the bloom is the chrome — no bottom dock at all. */
.hex-bloom[data-dock-mode="center"] .hex-bloom-dock {
  display: none;
}
/* The flower earns bigger tiles (no dock to clear) and folds like origami:
   deeper fold angle, harder scale-down, slower open. */
.hex-bloom[data-dock-mode="center"] {
  /* Modest fallback only — sizeCenterFlower() in JS overrides --tile-w/-h
     inline against the ACTUAL rendered sphere radius (game.getSphereScreen)
     the instant the menu opens, which is the only way "fits inside the
     sphere" holds at every board size and zoom level. A fixed px guess
     failed twice in testing (too small, then bigger than the sphere itself)
     because the sphere's own on-screen size moves with board size and zoom
     while a CSS constant does not. */
  --tile-w: 84px;
  --tile-h: 96px;
  --fold: 104deg;
  --fold-scale: 0.5;
  --fold-ms: 340ms;
}
.hex-bloom[data-context-menu="true"] {
  --fold: 88deg;
  --fold-scale: 0.68;
  --fold-ms: 140ms;
}
.hex-bloom[data-icon-menu="true"] {
  --border-w: 1px;
  --hb-fill: var(--hb-paper);
  --hb-fill-hover: var(--hb-paper);
  --hb-stroke: var(--hb-ink);
}
.hex-bloom[data-icon-menu="true"] .hb-hex { filter: none; }
.hex-bloom[data-icon-menu="true"] .hb-hex:hover::before,
.hex-bloom[data-icon-menu="true"] .hb-hex:focus-visible::before {
  inset: var(--border-w);
  background: var(--hb-paper);
}
.hex-bloom[data-icon-menu="true"] .hb-hex.is-active::before {
  background: var(--hb-ink);
}
/* Depth that reads at rest: a convex cap viewed slightly off-axis, with a
   short perspective and z-graded shadows. The center rides forward while
   the ring falls away, matching the sphere underneath instead of forming
   the old inside-out bowl. */
/* Spherical seating rotates tiles about their OWN centers (sphere faces
   curve about their centroids, not their inner edges — edge-hinging is what
   broke the tessellation). Overrides place()'s inline fold origin, so the
   fold becomes a center flip; the radial stagger keeps the bloom feel. */
.hex-bloom[data-dock-mode="center"] .hb-hex {
  transform-origin: 50% 50% !important;
}
.hex-bloom[data-dock-mode="center"] .hex-bloom-stage {
  /* Longer than the bottom-dock's 1100px default would be, but longer than
     the earlier 700px here: bigger tiles at the old short distance was
     over-foreshortening (the faceted/octagon look in Luke's screenshot). */
  perspective: 620px;
  perspective-origin: 50% 44%;
  /* No baked tilt: pointer parallax owns the stage transform (JS), so the
     flower sits perfectly aligned at rest and gains depth through motion.
     Transform transition off — the rAF lerp is the damper. */
  transition: opacity 0.12s ease, visibility 0.12s;
  transform-origin: 50% 50%;
}
.hex-bloom[data-dome="true"] .hex-bloom-stage {
  transform-style: preserve-3d;
  transform-origin: 50% 50%;
}
.hex-bloom[data-dome="true"]:not([data-dock-mode="center"]) .hex-bloom-stage {
  perspective: 760px;
  perspective-origin: 50% 100%;
}
.hex-bloom[data-dock-mode="center"] .hb-hex.shown {
  /* Subtle z-graded shadow; max() clamps the recessed center to zero so a
     negative blur can never invalidate the whole filter. */
  filter:
    drop-shadow(
      0
      calc(max(var(--dz, 0px), 0px) * 0.07 + var(--hov, 0px) * 0.25)
      calc(max(var(--dz, 0px), 0px) * 0.13 + 2px)
      rgba(0, 0, 0, 0.26)
    )
    drop-shadow(0 0 2px var(--hb-paper));
}
.hex-bloom[data-icon-menu="true"]:not([data-dome="true"]) .hb-hex.shown {
  /* The flat center flower is still one thin object hovering above the
     sphere. A restrained shared shadow gives the pointer tilt something to
     reveal without making seven independent cards. */
  filter: drop-shadow(0 2px 3px color-mix(in srgb, var(--hb-ink) 18%, transparent));
}
.hex-bloom[data-dome="true"] .hb-hex {
  backface-visibility: hidden;
}
/* Help corner — its own seat, lower right, always idle-sized. It never
   grows with the bloom: it is reference chrome, not part of the flower. */
.hex-bloom-corner {
  position: absolute;
  /* Keep the bare glyph fully inside the visual viewport. Two pixels left
     its stroked circle clipped by desktop browser chrome and mobile bars. */
  right: max(14px, calc(env(safe-area-inset-right, 0px) + 10px));
  bottom: max(12px, calc(env(safe-area-inset-bottom, 0px) + 10px));
  z-index: 3;
  pointer-events: auto;
}
.hex-bloom-corner .hb-hex.is-dock {
  position: relative;
  left: auto;
  top: auto;
  margin: 0;
  width: var(--tile-w-dock-idle);
  height: var(--tile-h-dock-idle);
  pointer-events: auto;
  /* No hex around the ? — bare glyph, same quiet treatment as the idle
     Restart / Flag icons, one step lighter. */
  clip-path: none;
  background: transparent;
  filter: none;
  transition:
    background 0.2s ease,
    color 0.2s ease,
    filter 0.2s ease,
    opacity 0.2s ease;
}
.hex-bloom-corner .hb-hex.is-dock::before {
  opacity: 0;
  background: transparent;
}
.hex-bloom-corner .hb-hex.is-dock .hb-glyph {
  color: var(--hb-ink);
  opacity: 0.6;
  filter:
    drop-shadow(0 0 2px var(--hb-paper))
    drop-shadow(0 0 1px var(--hb-paper));
}
.hex-bloom-corner .hb-hex.is-dock:hover .hb-glyph,
.hex-bloom-corner .hb-hex.is-dock:focus-visible .hb-glyph {
  opacity: 1;
}

/* Flag mode live: the dock tile reads as a planted flag (red face) via the
   shared .is-flag-icon.is-active language. */

/* While board has attention, whole dock recedes */
.hex-bloom[data-sphere-busy="true"][data-phase="closed"] .hex-bloom-dock,
.hex-bloom[data-sphere-busy="true"][data-phase="closed"] .hex-bloom-corner {
  opacity: 0;
}
.hex-bloom[data-sphere-busy="true"][data-phase="closed"] .hb-hex.is-dock {
  pointer-events: none !important;
}
@media (prefers-reduced-motion: reduce) {
  /* Stage / .hb-hex reduced-motion handling lives in the !important block
     near the end of this file — only the dock's own fade is decided here. */
  .hex-bloom-dock {
    transition: opacity 0.12s ease;
  }
}
@media (max-width: 400px) {
  .hex-bloom {
    --tile-w: 66px;
    --tile-h: 76px;
    --tile-w-dock-idle: 36px;
    --tile-h-dock-idle: 42px;
  }
  .hex-bloom[data-phase="open"] .hex-bloom-dock {
    --dock-rise: -28px;
  }
}

/* ---- Hex tile (clex language) ---- */
.hb-hex {
  position: absolute;
  width: var(--tile-w);
  height: var(--tile-h);
  margin-left: calc(var(--tile-w) / -2);
  /* Placed via `bottom` (see place()) — the centering margin lives on the
     bottom side so tiles stay glued to the dock when the mobile URL bar
     resizes the viewport. Dock tiles (.is-dock) reset margin to 0. */
  margin-bottom: calc(var(--tile-h) / -2);
  display: grid;
  place-items: center;
  clip-path: var(--hex-clip);
  background: var(--hb-stroke);
  color: var(--hb-ink);
  border: 0;
  padding: 0;
  cursor: pointer;
  pointer-events: auto;
  /* iOS Safari ignores body-level touch-action for its double-tap-zoom
     heuristic — it must sit on the touched element. Open+close is two taps
     on the same spot; without this Safari smart-zooms and position:fixed
     chrome slides around the visual viewport until the zoom settles. */
  touch-action: manipulation;
  transform-style: preserve-3d;
  transition:
    transform var(--fold-ms) cubic-bezier(0.22, 1, 0.3, 1),
    opacity calc(var(--fold-ms) * 0.85) ease,
    background 0.15s ease,
    color 0.15s ease,
    width var(--rise-ms) cubic-bezier(0.22, 1, 0.3, 1),
    height var(--rise-ms) cubic-bezier(0.22, 1, 0.3, 1),
    margin var(--rise-ms) cubic-bezier(0.22, 1, 0.3, 1);
  will-change: transform, opacity;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
  filter:
    drop-shadow(0 0 3px var(--hb-paper))
    drop-shadow(0 1px 0 var(--hb-paper));
}
.hb-hex::before {
  content: "";
  position: absolute;
  inset: var(--border-w);
  clip-path: var(--hex-clip);
  background: var(--hb-fill);
  transition: inset 0.15s ease, background 0.2s ease;
  z-index: 0;
}
.hb-hex .hb-label {
  position: relative;
  z-index: 1;
  max-width: 88%;
  text-align: center;
  font-size: 11px;
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1.12;
  pointer-events: none;
}
.hb-hex .hb-label[data-size="sm"] { font-size: 10px; }
.hb-hex .hb-label[data-size="xs"] { font-size: 9px; }

/* Icon glyphs on primaries / icon-bearing leaves */
.hb-hex .hb-glyph {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  pointer-events: none;
  color: inherit;
  transition: opacity 0.18s ease;
}
.hb-hex .hb-icon {
  display: block;
  width: 26px;
  height: 26px;
}
.hb-hex.is-primary .hb-glyph {
  width: 30px;
  height: 30px;
}
.hb-hex.is-primary .hb-icon {
  width: 28px;
  height: 28px;
}
.hb-hex.is-sub .hb-glyph {
  width: 24px;
  height: 24px;
}
.hb-hex.is-sub .hb-icon {
  width: 22px;
  height: 22px;
}
/* Visually hide label text while keeping it for SR / aria mirror */
.hb-hex .hb-label.sr-visual-hide,
.hb-hex .hb-label.hb-label-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* Size primary: nested-hex icon + letter badge */
.hb-hex.is-primary.has-badge {
  display: grid;
  place-items: center;
}
.hb-hex.is-primary.has-badge .hb-glyph {
  opacity: 0.35;
  position: absolute;
  z-index: 1;
}
.hb-hex.is-primary.has-badge .hb-label {
  position: relative;
  z-index: 2;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.02em;
  max-width: none;
}
/* Hybrid primaries: small glyph + short word */
.hb-hex.is-primary:not(.has-badge) {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  padding: 4px 2px 6px;
}
.hb-hex.is-primary:not(.has-badge) .hb-glyph {
  width: 22px;
  height: 22px;
}
.hb-hex.is-primary:not(.has-badge) .hb-icon {
  width: 20px;
  height: 20px;
}
.hb-hex.is-primary:not(.has-badge) .hb-label:not(.sr-visual-hide) {
  font-size: 9px;
  font-weight: 650;
  letter-spacing: 0.01em;
  line-height: 1.05;
  max-width: 90%;
}
.hb-hex.is-active .hb-glyph,
.hb-hex.is-chosen .hb-glyph {
  color: inherit;
}
@media (hover: hover) and (pointer: fine) {
  .hb-hex:hover .hb-icon,
  .hb-hex:focus-visible .hb-icon {
    transform: scale(1.08);
  }
  .hb-hex .hb-icon {
    transition: transform 0.2s cubic-bezier(0.22, 1, 0.3, 1);
  }
}

/* Dig = open honeycomb cell (hollow stroke hex) */
.hb-hex.is-dig-icon .hb-icon {
  stroke-width: 2;
}

/* Flag = solid red face — same language as in-game flags */
.hb-hex.is-flag-icon {
  color: #ff0000;
}
.hb-hex.is-flag-icon.is-active,
.hb-hex.is-flag-icon.is-chosen {
  background: #ff0000;
  color: #ff0000;
}
.hb-hex.is-flag-icon.is-active::before,
.hb-hex.is-flag-icon.is-chosen::before {
  background: color-mix(in srgb, var(--hb-paper) 12%, #ff0000);
}
.hb-hex.is-flag-icon.is-active .hb-icon,
.hb-hex.is-flag-icon.is-chosen .hb-icon {
  color: #ff0000;
}

/* Contextual flower: Home and Reset share a warm navigation/action signal,
   while Flag stays neutral until the mode is actually active. Tile materials
   never change — state lives in the glyphs only. */
.hex-bloom[data-icon-menu="true"] .cat-home .hb-glyph,
.hex-bloom[data-icon-menu="true"] .is-center-reset .hb-glyph,
.hex-bloom[data-icon-menu="true"] .cat-reset .hb-glyph {
  color: #ffd400;
}
.hex-bloom[data-icon-menu="true"] .cat-undo .hb-glyph {
  color: #18a64a;
}
.hex-bloom[data-icon-menu="true"] .is-flag-toggle .hb-glyph {
  color: var(--hb-ink);
}
.hex-bloom[data-icon-menu="true"] .is-flag-toggle.is-mode-active .hb-glyph {
  color: #ff2200;
}
.hex-bloom[data-icon-menu="true"] .hb-hex.is-primary .hb-glyph {
  width: clamp(44px, calc(var(--tile-h) * 0.38), 66px);
  height: clamp(44px, calc(var(--tile-h) * 0.38), 66px);
}
.hex-bloom[data-icon-menu="true"] .hb-hex.is-primary .hb-icon {
  width: clamp(40px, calc(var(--tile-h) * 0.34), 60px);
  height: clamp(40px, calc(var(--tile-h) * 0.34), 60px);
}
.hex-bloom[data-icon-menu="true"] .hb-icon-sizeXL {
  overflow: visible;
  transform: scale(1.18);
  transform-origin: 50% 50%;
}
.hex-bloom[data-icon-menu="true"] .hb-hex.is-sub .hb-glyph {
  width: clamp(44px, calc(var(--tile-h) * 0.36), 62px);
  height: clamp(44px, calc(var(--tile-h) * 0.36), 62px);
}
.hex-bloom[data-icon-menu="true"] .hb-hex.is-sub .hb-icon {
  width: clamp(40px, calc(var(--tile-h) * 0.32), 56px);
  height: clamp(40px, calc(var(--tile-h) * 0.32), 56px);
}

/* Theme primary = plain circle; tint from current theme when available */
.hb-hex.is-theme-icon .hb-icon {
  stroke-width: 2.1;
  color: var(--theme-edge, currentColor);
}
.hb-hex.is-theme-icon .hb-icon circle {
  fill: var(--theme-fill, transparent);
  fill-opacity: 0.92;
  stroke: var(--theme-edge, currentColor);
}

/* Theme leaves: the hex face is painted like that theme’s shell/field */
.hb-hex.is-theme-swatch {
  background: var(--theme-edge, var(--hb-stroke));
  color: var(--theme-ink, var(--hb-ink));
}
.hb-hex.is-theme-swatch::before {
  background: var(--theme-fill, var(--hb-fill));
  inset: var(--border-w);
}
.hb-hex.is-theme-swatch .hb-theme-dot {
  position: relative;
  z-index: 1;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--theme-field, transparent);
  box-shadow:
    0 0 0 1.5px var(--theme-edge, currentColor),
    inset 0 0 0 1px color-mix(in srgb, var(--theme-field) 40%, var(--theme-edge));
  pointer-events: none;
}
.hb-hex.is-theme-swatch.is-chosen {
  background: var(--theme-accent, #ff0000);
  color: var(--theme-ink, #fff);
}
.hb-hex.is-theme-swatch.is-chosen::before {
  background: var(--theme-fill, var(--hb-fill));
  inset: 3px;
}
.hb-hex.is-theme-swatch.is-chosen .hb-theme-dot {
  box-shadow:
    0 0 0 2px var(--theme-accent, #ff0000),
    inset 0 0 0 1px var(--theme-edge, #000);
}
@media (hover: hover) and (pointer: fine) {
  .hb-hex.is-theme-swatch:hover::before {
    inset: calc(var(--border-w) + 1px);
    background: var(--theme-fill, var(--hb-fill-hover));
  }
}

@media (hover: hover) and (pointer: fine) {
  .hb-hex:hover::before,
  .hb-hex:focus-visible::before {
    background: var(--hb-fill-hover);
    inset: calc(var(--border-w) + 1px);
  }
}
.hb-hex:focus-visible {
  background: var(--hb-accent);
}

/* Dock hexes */
.hb-hex.is-dock {
  z-index: 40;
  color: var(--hb-ink);
  background: var(--hb-stroke);
  pointer-events: auto;
  filter:
    drop-shadow(0 0 2px var(--hb-paper))
    drop-shadow(0 0 1px var(--hb-paper));
}
.hb-hex.is-dock::before {
  background: var(--hb-fill);
  inset: var(--border-w);
  transition: inset 0.2s ease, background 0.2s ease, opacity 0.2s ease;
}
.hb-hex.is-dock .hb-glyph {
  width: 55%;
  height: 55%;
  max-width: 28px;
  max-height: 28px;
  color: var(--hb-ink);
  transition: width 0.2s ease, height 0.2s ease;
}
.hb-hex.is-dock .hb-icon {
  width: 100%;
  height: 100%;
}
.hb-hex.is-dock .hb-label {
  font-size: 11px;
  font-weight: 650;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--hb-ink);
}

/* ---- Idle (closed): sides are borderless icons; menu is a quiet ring + hex icon ---- */
.hex-bloom[data-phase="closed"] .hb-hex.is-dock-side {
  background: transparent;
  filter: none;
}
.hex-bloom[data-phase="closed"] .hb-hex.is-dock-side::before {
  opacity: 0;
  background: transparent;
}
.hex-bloom[data-phase="closed"] .hb-hex.is-dock-side .hb-glyph {
  color: var(--hb-ink);
  opacity: 0.72;
  filter:
    drop-shadow(0 0 2px var(--hb-paper))
    drop-shadow(0 0 1px var(--hb-paper));
}
.hex-bloom[data-phase="closed"] .hb-hex.is-dock-side:hover .hb-glyph,
.hex-bloom[data-phase="closed"] .hb-hex.is-dock-side:focus-visible .hb-glyph {
  opacity: 1;
}
.hex-bloom .hb-hex.is-dock-reset .hb-glyph {
  color: #18a64a;
}
/* Flag mode on: the dock flag turns red — full strength in every phase
   (the idle rule above otherwise pins side glyphs to ink at 0.72). */
.hex-bloom .hb-hex.is-dock-flag.is-flag-icon .hb-glyph {
  color: #ff2200;
  opacity: 1;
}
/* ?seed=bare: idle seed is JUST the gear — hex face appears on activation,
   exactly the treatment Reset and ? already get when closed. */
.hex-bloom[data-seed="bare"][data-phase="closed"] .hex-bloom-dock .hb-glyph {
  width: 78%;
  height: 78%;
  max-width: 36px;
  max-height: 36px;
}
.hex-bloom[data-seed="bare"][data-phase="closed"] .hb-hex.is-dock-menu {
  background: transparent;
  filter: none;
}
.hex-bloom[data-seed="bare"][data-phase="closed"] .hb-hex.is-dock-menu::before {
  opacity: 0;
  background: transparent;
}
.hex-bloom[data-seed="bare"][data-phase="closed"] .hb-hex.is-dock-menu .hb-glyph {
  color: var(--hb-ink);
  opacity: 0.72;
  filter:
    drop-shadow(0 0 2px var(--hb-paper))
    drop-shadow(0 0 1px var(--hb-paper));
}
.hex-bloom[data-seed="bare"][data-phase="closed"] .hb-hex.is-dock-menu:hover .hb-glyph,
.hex-bloom[data-seed="bare"][data-phase="closed"] .hb-hex.is-dock-menu:focus-visible .hb-glyph {
  opacity: 1;
}

/* Menu: light outline + hollow-hex icon (reads as “open”) */
.hex-bloom[data-phase="closed"] .hb-hex.is-dock-menu {
  background: var(--hb-stroke);
  filter:
    drop-shadow(0 0 2px var(--hb-paper))
    drop-shadow(0 0 1px var(--hb-paper));
}
.hex-bloom[data-phase="closed"] .hb-hex.is-dock-menu::before {
  background: var(--hb-fill);
  inset: var(--border-w);
  opacity: 1;
}
.hex-bloom[data-phase="closed"] .hb-hex.is-dock-menu .hb-glyph {
  opacity: 1;
}

/* Default and bottom-dome launch from one deliberate horizon tab. Its full
   88px hex leaves a 44px exposed target; the other two actions retain their
   seats invisibly so the seed never jumps sideways when it blooms. */
.hex-bloom[data-bottom-seed="true"][data-phase="closed"] .hex-bloom-dock {
  --dock-rise: var(--seed-sink);
}
.hex-bloom[data-bottom-seed="true"][data-phase="closed"] .hb-hex.is-dock-side {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: scale(0.72);
}
.hex-bloom[data-bottom-seed="true"][data-phase="closed"] .hb-hex.is-dock-menu {
  width: var(--tile-w);
  height: var(--tile-h);
  background: var(--hb-ink);
  color: var(--hb-paper);
  filter: none;
}
.hex-bloom[data-bottom-seed="true"][data-phase="closed"] .hb-hex.is-dock-menu::before {
  inset: 0;
  opacity: 1;
  background: var(--hb-ink);
}
.hex-bloom[data-bottom-seed="true"][data-phase="closed"] .hb-hex.is-dock-menu .hb-glyph {
  width: 36px;
  height: 36px;
  max-width: none;
  max-height: none;
  color: var(--hb-paper);
  transform: translateY(calc(var(--seed-sink) * -0.48));
}
.hex-bloom[data-bottom-seed="true"][data-phase="open"] .hb-hex.is-dock-menu .hb-glyph,
.hex-bloom[data-bottom-seed="true"][data-phase="falling"] .hb-hex.is-dock-menu .hb-glyph {
  transform: translateY(0);
}

/* ---- Open: full bloom borders on all three; menu = solid × ---- */
.hex-bloom[data-phase="open"] .hb-hex.is-dock-side,
.hex-bloom[data-phase="falling"] .hb-hex.is-dock-side {
  background: var(--hb-stroke);
  filter:
    drop-shadow(0 0 2px var(--hb-paper))
    drop-shadow(0 0 1px var(--hb-paper));
  z-index: 41;
}
.hex-bloom[data-phase="open"] .hb-hex.is-dock-side::before,
.hex-bloom[data-phase="falling"] .hb-hex.is-dock-side::before {
  opacity: 1;
  background: var(--hb-fill);
  inset: var(--border-w);
}
.hex-bloom[data-phase="open"] .hb-hex.is-dock-menu,
.hex-bloom[data-phase="open"][data-dock="ready"] .hb-hex.is-dock-menu {
  background: var(--hb-ink);
  color: var(--hb-paper);
  z-index: 42;
}
.hex-bloom[data-phase="open"] .hb-hex.is-dock-menu .hb-glyph,
.hex-bloom[data-phase="open"][data-dock="ready"] .hb-hex.is-dock-menu .hb-glyph {
  color: var(--hb-paper);
}
.hex-bloom[data-phase="open"] .hb-hex.is-dock-menu::before,
.hex-bloom[data-phase="open"][data-dock="ready"] .hb-hex.is-dock-menu::before {
  background: var(--hb-ink);
  inset: 0;
  opacity: 1;
}
.hex-bloom[data-phase="open"] .hb-hex.is-dock-menu .hb-label,
.hex-bloom[data-phase="open"][data-dock="ready"] .hb-hex.is-dock-menu .hb-label {
  color: var(--hb-paper);
  font-size: clamp(16px, 4vw, 22px);
  font-weight: 500;
  opacity: 1;
}
.hex-bloom[data-phase="open"] .hex-bloom-dock .hb-hex.is-dock .hb-glyph,
.hex-bloom[data-phase="open"][data-dock="ready"] .hex-bloom-dock .hb-hex.is-dock .hb-glyph {
  width: clamp(44px, calc(var(--tile-h) * 0.38), 66px);
  height: clamp(44px, calc(var(--tile-h) * 0.38), 66px);
  max-width: none;
  max-height: none;
}
.hex-bloom[data-phase="open"] .hex-bloom-dock .hb-hex.is-dock .hb-icon,
.hex-bloom[data-phase="open"][data-dock="ready"] .hex-bloom-dock .hb-hex.is-dock .hb-icon {
  width: clamp(40px, calc(var(--tile-h) * 0.34), 60px);
  height: clamp(40px, calc(var(--tile-h) * 0.34), 60px);
}
.hex-bloom[data-phase="closed"] .hb-hex.is-dock {
  pointer-events: auto;
}

/* Primary ring */
.hb-hex.is-primary {
  z-index: 20;
  color: var(--hb-ink);
}
.hb-hex.is-primary.is-active {
  background: var(--hb-accent);
  color: var(--hb-active-ink);
  z-index: 28;
}
.hb-hex.is-primary.is-active::before {
  background: var(--hb-active-fill);
  inset: 2px;
}
.hb-hex.is-primary.is-active .hb-label {
  color: var(--hb-active-ink);
}

.hex-bloom[data-branch] .hb-hex.is-primary:not(.is-active) {
  opacity: 1;
}
.hex-bloom[data-branch] .hb-hex.is-primary:not(.is-active) .hb-glyph {
  opacity: 0.42;
}

/* Sub / leaf ring */
.hb-hex.is-sub {
  z-index: 24;
  color: var(--hb-ink);
}
.hb-hex.is-sub .hb-label {
  color: var(--hb-ink);
  font-size: 10px;
}
.hb-hex.is-sub.is-chosen {
  background: var(--hb-accent);
  color: var(--hb-active-ink);
  z-index: 26;
}
.hb-hex.is-sub.is-chosen::before {
  background: var(--hb-active-fill);
  inset: 2px;
}
.hb-hex.is-sub.is-chosen .hb-label {
  color: var(--hb-active-ink);
}

/* Fold / unfold (clex) */
.hb-hex.folded {
  opacity: 0;
  pointer-events: none;
  transform:
    translate(var(--tx, 0), var(--ty, 0))
    rotate3d(var(--ax, 0), var(--ay, 1), 0, var(--fold, 82deg))
    scale(var(--fold-scale, 0.86));
}
.hb-hex.shown {
  opacity: 1;
  /* --domeax/--domeay/--dome/--dz/--dscale: the ?dome=1 bowl (applyCenterDome)
     — a single rotation around each tile's own tangent axis, the exact
     "point this face at the sphere's center" transform (external review,
     2026-08-10: a two-axis rotateX+rotateY split does not commute and only
     half-shares an axis between neighbors — one rotation has no such flaw).
     --hov: hover/select lift. Defaults keep everything flat. */
  transform:
    translate(var(--tx, 0), var(--ty, 0))
    translateZ(calc(var(--dz, 0px) + var(--hov, 0px)))
    rotate3d(var(--domeax, 0), var(--domeay, 1), 0, var(--dome, 0deg))
    scale(var(--dscale, 1));
}
/* Tiles flip up a touch toward the player on hover / keyboard focus.
   Snappier than the fold: the lift must not ride --fold-ms (340ms in
   center mode read as lag, not response). */
.hex-bloom[data-dome="true"] .hb-hex.is-primary.shown:hover,
.hex-bloom[data-dome="true"] .hb-hex.is-primary.shown:focus-visible {
  --hov: 14px;
  transition-duration: 130ms;
}
.hex-bloom[data-dome="true"] .hb-hex.is-primary.shown:active {
  --hov: 7px;
}

/* ---- Query studies: chrome inhabits the sphere instead of covering it ---- */
.hex-bloom[data-face-takeover="true"] .hex-bloom-scrim,
.hex-bloom[data-equator-ribbon="true"] .hex-bloom-scrim {
  background: color-mix(in srgb, var(--hb-paper) 7%, transparent);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* Face takeover uses the renderer's real projected polygons. Each control is
   therefore the exact size, skew and neighbour seam of the board face below. */
.hex-bloom[data-face-takeover="true"] .hb-face-action {
  margin: 0;
  clip-path: var(--face-poly);
  background: color-mix(in srgb, var(--hb-ink) 78%, transparent);
  transform-origin: 50% 50% !important;
  transition:
    transform 210ms cubic-bezier(0.22, 1, 0.3, 1),
    opacity 160ms ease,
    filter 140ms ease;
}
.hex-bloom[data-face-takeover="true"] .hb-face-action::before {
  inset: 1.5px;
  clip-path: var(--face-poly);
  background: color-mix(in srgb, var(--hb-paper) 92%, transparent);
}
.hex-bloom[data-face-takeover="true"][data-icon-menu="true"] .hb-hex.hb-face-action .hb-glyph,
.hex-bloom[data-face-takeover="true"][data-icon-menu="true"] .hb-hex.hb-face-action .hb-icon {
  width: var(--face-icon);
  height: var(--face-icon);
  max-width: none;
  max-height: none;
}
.hex-bloom[data-face-takeover="true"] .hb-face-action.folded {
  transform: scale(0.58);
  opacity: 0;
}
.hex-bloom[data-face-takeover="true"] .hb-face-action.shown {
  transform: scale(0.97);
  opacity: 0.96;
  filter: drop-shadow(0 3px 5px color-mix(in srgb, var(--hb-ink) 28%, transparent));
}
.hex-bloom[data-face-takeover="true"] .hb-face-action.shown:hover,
.hex-bloom[data-face-takeover="true"] .hb-face-action.shown:focus-visible {
  transform: scale(1.055);
  opacity: 1;
  z-index: 140 !important;
}
.hex-bloom[data-face-takeover="true"] .hb-face-center.shown {
  filter: drop-shadow(0 5px 8px color-mix(in srgb, var(--hb-ink) 38%, transparent));
}

/* Equator ribbon: seven controls orbit one shared belt. Screen position is
   recalculated in JS; scale, opacity and blur carry front/back depth. */
.hex-bloom[data-equator-ribbon="true"] .hb-ribbon-action {
  margin-left: 0;
  margin-top: 0;
  margin-bottom: 0;
  transform-origin: 50% 50% !important;
  cursor: grab;
  touch-action: none;
  transition:
    transform 180ms cubic-bezier(0.22, 1, 0.3, 1),
    opacity 150ms ease,
    filter 150ms ease;
}
.hex-bloom[data-equator-ribbon="true"][data-icon-menu="true"] .hb-hex.hb-ribbon-action .hb-glyph {
  width: 44%;
  height: 44%;
  max-width: 42px;
  max-height: 42px;
}
.hex-bloom[data-equator-ribbon="true"][data-icon-menu="true"] .hb-hex.hb-ribbon-action .hb-icon {
  width: 100%;
  height: 100%;
}
.hex-bloom[data-equator-ribbon="true"] .hb-ribbon-action.folded {
  transform: translate(-50%, -50%) scale(0.28);
  opacity: 0;
}
.hex-bloom[data-equator-ribbon="true"] .hb-ribbon-action.shown {
  transform: translate(-50%, -50%) scale(var(--ribbon-scale, 1));
  opacity: var(--ribbon-opacity, 1);
  filter:
    blur(var(--ribbon-blur, 0px))
    drop-shadow(0 4px 7px color-mix(in srgb, var(--hb-ink) 30%, transparent));
}
.hex-bloom[data-equator-ribbon="true"] .hb-ribbon-action.shown:hover,
.hex-bloom[data-equator-ribbon="true"] .hb-ribbon-action.shown:focus-visible {
  opacity: 1;
  filter: drop-shadow(0 6px 10px color-mix(in srgb, var(--hb-ink) 38%, transparent));
}
.hex-bloom[data-equator-ribbon="true"][data-ribbon-dragging="true"] .hb-ribbon-action {
  cursor: grabbing;
  transition: none;
}

/* ---- Spatial shell studies -------------------------------------------------
   Both modes borrow the semantic seven-control flower, while every shell and
   interior surface now comes from the live sphere renderer itself. */
.hex-bloom[data-egg-shell="true"] .hex-bloom-scrim,
.hex-bloom[data-inner-chamber="true"] .hex-bloom-scrim {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.hex-bloom[data-egg-shell="true"] .hex-bloom-scrim {
  background: color-mix(in srgb, var(--hb-paper) 5%, transparent);
}
.hex-bloom[data-inner-chamber="true"] .hex-bloom-scrim {
  background: color-mix(in srgb, var(--hb-paper) 5%, transparent);
}
.hex-bloom[data-egg-shell="true"] {
  --fold-ms: 220ms;
}
.hex-bloom[data-inner-chamber="true"] {
  --fold-ms: 420ms;
}

.hb-shell-scene {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  perspective: 700px;
  perspective-origin: 50% 50%;
  transition: opacity 90ms ease, visibility 90ms ease;
}
.hex-bloom[data-open="true"] .hb-shell-scene,
.hex-bloom[data-phase="falling"] .hb-shell-scene {
  opacity: 1;
  visibility: visible;
}

.hex-bloom[data-egg-shell="true"] .hex-bloom-stage {
  perspective: 820px;
}
.hex-bloom[data-egg-shell="true"] .hb-hex.shown {
  filter:
    drop-shadow(0 4px 8px color-mix(in srgb, var(--hb-ink) 30%, transparent))
    drop-shadow(0 0 2px var(--hb-paper));
}

.hex-bloom[data-inner-chamber="true"] .hex-bloom-stage {
  perspective: none;
}
.hex-bloom[data-inner-chamber="true"] .hb-hex.shown {
  filter:
    drop-shadow(0 5px 11px color-mix(in srgb, var(--hb-ink) 42%, transparent))
    drop-shadow(0 0 4px var(--hb-paper));
}

/* ---- Polar control studies ------------------------------------------------
   Four independent mechanisms share one stable landmark: the north pole.
   The decorative object sits behind the real semantic buttons; it never
   intercepts input and every action remains a normal labelled control. */
.hex-bloom[data-polar-study="true"] .hex-bloom-scrim {
  background: color-mix(in srgb, var(--hb-paper) 10%, transparent);
  -webkit-backdrop-filter: blur(1.5px) saturate(0.94);
  backdrop-filter: blur(1.5px) saturate(0.94);
}
.hb-polar-object {
  position: absolute;
  left: var(--polar-cx, 50%);
  top: var(--polar-cy, 35%);
  width: 1px;
  height: 1px;
  color: var(--hb-ink);
  opacity: 0;
  transform: translate(-50%, -50%) translateY(calc(var(--polar-unit) * 0.7)) scale(0.82);
  transform-style: preserve-3d;
  transition:
    opacity 180ms ease,
    transform 360ms cubic-bezier(0.22, 1, 0.3, 1);
}
.hex-bloom[data-open="true"] .hb-polar-object {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}
.hb-polar-object > div {
  position: absolute;
  box-sizing: border-box;
}
.hex-bloom[data-polar-study="true"] .hb-polar-action {
  transform-origin: 50% 50% !important;
  filter:
    drop-shadow(0 4px 7px color-mix(in srgb, var(--hb-ink) 28%, transparent))
    drop-shadow(0 0 2px var(--hb-paper));
}
.hex-bloom[data-polar-study="true"] .hb-polar-reset .hb-glyph {
  color: #ffd400;
}

/* Capstan: a faceted spindle physically rises out of the polar collar. */
.hb-polar-object--capstan {
  perspective: 620px;
}
.hb-polar-object--capstan .hb-polar-collar {
  left: calc(var(--polar-unit) * -2.35);
  top: calc(var(--polar-unit) * -1.05);
  width: calc(var(--polar-unit) * 4.7);
  height: calc(var(--polar-unit) * 1.7);
  border-radius: 50%;
  background: var(--hb-paper);
  border: 1.5px solid var(--hb-ink);
  box-shadow: 0 8px 18px color-mix(in srgb, var(--hb-ink) 24%, transparent);
}
.hb-polar-object--capstan .hb-polar-shaft {
  left: calc(var(--polar-unit) * -1.86);
  top: calc(var(--polar-unit) * -0.35);
  width: calc(var(--polar-unit) * 3.72);
  height: calc(var(--polar-unit) * 4.75);
  clip-path: polygon(0 0, 100% 0, 88% 100%, 12% 100%);
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--hb-paper) 82%, var(--hb-ink)),
    var(--hb-paper) 46%,
    color-mix(in srgb, var(--hb-paper) 72%, var(--hb-ink))
  );
  border-bottom: 2px solid var(--hb-ink);
}
.hb-polar-object--capstan .hb-polar-top {
  left: calc(var(--polar-unit) * -1.75);
  top: calc(var(--polar-unit) * -1.4);
  width: calc(var(--polar-unit) * 3.5);
  height: calc(var(--polar-unit) * 1.7);
  border-radius: 50%;
  background: var(--hb-paper);
  border: 2px solid var(--hb-ink);
}
.hb-polar-object--capstan .hb-polar-seam-left,
.hb-polar-object--capstan .hb-polar-seam-right {
  top: calc(var(--polar-unit) * -0.05);
  height: calc(var(--polar-unit) * 4.05);
  border-left: 1px solid color-mix(in srgb, var(--hb-ink) 34%, transparent);
}
.hb-polar-object--capstan .hb-polar-seam-left { left: calc(var(--polar-unit) * -0.7); }
.hb-polar-object--capstan .hb-polar-seam-right { left: calc(var(--polar-unit) * 0.7); }
.hex-bloom[data-polar-take="capstan"] .hb-polar-action.shown {
  transform: translateZ(calc(var(--polar-unit) * 0.12));
}

/* Crown: six geodesic vanes lock around one reset hub. */
.hb-polar-object--crown .hb-polar-collar {
  left: calc(var(--polar-unit) * -2.55);
  top: calc(var(--polar-unit) * -2.55);
  width: calc(var(--polar-unit) * 5.1);
  height: calc(var(--polar-unit) * 5.1);
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--hb-ink) 48%, transparent);
  box-shadow:
    inset 0 0 calc(var(--polar-unit) * 0.8) color-mix(in srgb, var(--hb-ink) 14%, transparent),
    0 9px 18px color-mix(in srgb, var(--hb-ink) 20%, transparent);
}
.hb-polar-object--crown .hb-polar-petal {
  left: calc(var(--polar-unit) * -0.68);
  top: calc(var(--polar-unit) * -2.7);
  width: calc(var(--polar-unit) * 1.36);
  height: calc(var(--polar-unit) * 2.25);
  transform-origin: 50% calc(var(--polar-unit) * 2.7);
  transform: rotate(calc(var(--petal-i) * 60deg));
  clip-path: polygon(50% 0, 100% 30%, 86% 100%, 14% 100%, 0 30%);
  background: color-mix(in srgb, var(--hb-paper) 84%, var(--hb-ink));
  border-top: 2px solid var(--hb-ink);
}
.hex-bloom[data-polar-take="crown"] .hb-polar-action.shown {
  --dz: calc(var(--polar-unit) * 0.1);
}

/* Drill: nested annuli telescope toward a quiet polar aperture. */
.hb-polar-object--drill .hb-polar-ring,
.hb-polar-object--drill .hb-polar-bore {
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
.hb-polar-object--drill .hb-polar-ring {
  border: 1.5px solid var(--hb-ink);
  background: color-mix(in srgb, var(--hb-paper) 80%, transparent);
  box-shadow: inset 0 0 calc(var(--polar-unit) * 0.6) color-mix(in srgb, var(--hb-ink) 13%, transparent);
}
.hb-polar-object--drill .hb-polar-ring--1 { width: calc(var(--polar-unit) * 2.25); height: calc(var(--polar-unit) * 2.25); }
.hb-polar-object--drill .hb-polar-ring--2 { width: calc(var(--polar-unit) * 4.25); height: calc(var(--polar-unit) * 4.25); }
.hb-polar-object--drill .hb-polar-ring--3 { width: calc(var(--polar-unit) * 7); height: calc(var(--polar-unit) * 7); opacity: 0.62; }
.hb-polar-object--drill .hb-polar-bore {
  width: calc(var(--polar-unit) * 1.15);
  height: calc(var(--polar-unit) * 1.15);
  background: var(--hb-ink);
  box-shadow: 0 0 calc(var(--polar-unit) * 0.45) color-mix(in srgb, var(--hb-ink) 35%, transparent);
}
.hex-bloom[data-polar-take="drill"] .hb-polar-action {
  clip-path: circle(50%);
}
.hex-bloom[data-polar-take="drill"] .hb-polar-action::before {
  clip-path: circle(50%);
}

/* Lid: one detached polar face becomes a shallow, screen-facing panel. */
.hb-polar-object--lid {
  perspective: 560px;
}
.hb-polar-object--lid .hb-polar-tether {
  left: calc(var(--polar-unit) * -0.15);
  top: calc(var(--polar-unit) * 2.15);
  width: calc(var(--polar-unit) * 0.3);
  height: calc(var(--polar-unit) * 2.4);
  background: var(--hb-ink);
  transform: rotate(12deg);
  transform-origin: 50% 0;
}
.hb-polar-object--lid .hb-polar-hinge {
  left: calc(var(--polar-unit) * -1.2);
  top: calc(var(--polar-unit) * 2.15);
  width: calc(var(--polar-unit) * 2.4);
  height: calc(var(--polar-unit) * 0.42);
  border-radius: 999px;
  background: var(--hb-ink);
}
.hb-polar-object--lid .hb-polar-panel,
.hb-polar-object--lid .hb-polar-panel-rim {
  left: calc(var(--polar-unit) * -2.95);
  top: calc(var(--polar-unit) * -2.6);
  width: calc(var(--polar-unit) * 5.9);
  height: calc(var(--polar-unit) * 5.2);
  clip-path: polygon(16% 0, 84% 0, 100% 25%, 100% 75%, 84% 100%, 16% 100%, 0 75%, 0 25%);
}
.hb-polar-object--lid .hb-polar-panel {
  background: color-mix(in srgb, var(--hb-paper) 92%, var(--hb-ink));
  box-shadow: 0 16px 30px color-mix(in srgb, var(--hb-ink) 28%, transparent);
}
.hb-polar-object--lid .hb-polar-panel-rim {
  background: transparent;
  border: 2px solid var(--hb-ink);
}
.hex-bloom[data-polar-take="lid"] .hex-bloom-stage {
  perspective: 640px;
}
.hex-bloom[data-polar-take="lid"] .hb-polar-action.shown {
  transform: translateZ(calc(var(--polar-unit) * 0.16)) rotateX(-3deg);
}

@media (prefers-reduced-motion: reduce) {
  .hb-polar-object,
  .hb-polar-object > div {
    transition-duration: 0ms !important;
  }
}



/* Stats hub */
.hex-bloom-hub {
  --hub-ink: var(--text-main, #000);
  --hub-halo: var(--bg-color, #fff);
  position: fixed;
  top: max(14px, env(safe-area-inset-top));
  left: 50%;
  transform: translateX(-50%) translateY(-4px);
  z-index: 56;
  display: flex;
  gap: 1.35rem;
  pointer-events: none;
  color: var(--hub-ink);
  font: 600 22px/1 "IBM Plex Sans", system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.14s ease, transform 0.14s ease, visibility 0.14s;
  text-shadow:
    0 0 12px var(--hub-halo),
    0 0 5px var(--hub-halo),
    0 1px 0 var(--hub-halo),
    0 -1px 0 var(--hub-halo),
    1px 0 0 var(--hub-halo),
    -1px 0 0 var(--hub-halo);
}
body[data-sphere-chrome="dark"] .hex-bloom-hub {
  --hub-ink: #fff;
  --hub-halo: #000;
}
.hex-bloom-hub[data-open="true"] {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}

.hex-bloom-tooltip {
  position: fixed;
  z-index: 90;
  max-width: min(220px, calc(100vw - 16px));
  padding: 5px 8px 6px;
  border: 1px solid var(--hb-paper);
  border-radius: 4px;
  background: var(--hb-ink);
  color: var(--hb-paper);
  box-shadow: 0 2px 10px color-mix(in srgb, var(--hb-ink) 28%, transparent);
  font-size: 11px;
  font-weight: 650;
  line-height: 1;
  letter-spacing: 0.01em;
  white-space: nowrap;
  pointer-events: none;
}
.hex-bloom-tooltip[hidden] {
  display: none;
}

.hex-bloom-live {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
  margin: -1px !important;
  padding: 0 !important;
}

/* Hide legacy gear/help chrome */
body.hex-bloom-ui .hud-help-fixed,
body.hex-bloom-ui .hud-cluster {
  display: none !important;
  pointer-events: none !important;
}
body.hex-bloom-ui .legacy-hud {
  display: block !important;
  position: fixed !important;
  left: -10000px !important;
  top: 0 !important;
  width: 0 !important;
  height: 0 !important;
  overflow: hidden !important;
  opacity: 0 !important;
  pointer-events: none !important;
}

/* While menu is the active surface, keep the board inert-looking */
body.hex-bloom-open .canvas-container {
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .hb-hex,
  .hex-bloom-scrim,
  .hex-bloom-stage,
  .hex-bloom-hub,
  .hb-shell-scene,
  #gameCanvas {
    transition: none !important;
    transition-delay: 0ms !important;
  }
  .hex-bloom {
    --rise-ms: 0ms;
  }
  .hb-hex.folded {
    transform: translate(var(--tx, 0), var(--ty, 0)) scale(0.92);
  }
}

@media (max-width: 400px) {
  .hex-bloom {
    --tile-w: 66px;
    --tile-h: 76px;
  }
  .hex-bloom[data-icon-menu="true"]:not([data-dock-mode="center"]) {
    --tile-w: 76px;
    --tile-h: 88px;
  }
  .hex-bloom[data-bottom-seed="true"][data-icon-menu="true"]:not([data-dock-mode="center"]) {
    --tile-w: 92px;
    --tile-h: 106px;
    --seed-sink: 53px;
  }
  .hb-hex .hb-label { font-size: 10px; }
}

/* Hub glyphs: bomb by the mine count, clock by the time. */
.hex-bloom-hub .hub-ico {
  width: 14px;
  height: 14px;
  opacity: 0.7;
  vertical-align: -2px;
  margin-right: -3px;
}
