html, body {
  margin: 0;
  padding: 0;
  background: #000;
  display: flex;
  justify-content: center;
  width: 100%;
  height: 100%;
}

/* Owner 2026-10-17: no word in the game can be highlighted or grabbed: no text selection, no long-press copy callout,
   no dragging text or images. Only the fields you type into (chat, villager orders, world name) keep selection. */
html, body, body * {
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
}
body input, body textarea, body [contenteditable="true"] {
  user-select: text;
  -webkit-user-select: text;
  -webkit-touch-callout: default;
}

/* Task 34: the game menu's keyboard focus is always visible (components/GameMenu.tsx) */
.cc-menu button:focus-visible, .cc-menu input:focus-visible, .cc-menu-btn:focus-visible {
  outline: 3px solid #ffd54a;
  outline-offset: 2px;
}
.cc-menu button:disabled { opacity: 0.5; }

/* Phase 2: the MAIN MENU (components/GameMenu.tsx MainMenu, the approved 9:16 mockup), in the owner's art direction
   (Civ V and VI as inspiration, never their assets): illustrated and warm, serif type, cards framed like parchment
   banners in brass. The live world turns behind it (components/MenuBackdrop.tsx), so the sheet is clear in the middle:
   a warm wash at the top behind the title and a deeper one at the bottom behind the cards. No blur filter (a blur over
   the WebGL canvas costs every frame on a phone) and nothing animated in CSS: the motion is the world itself.
   Portrait first; side by side in landscape. */
.cc-main {
  --cc-serif: Georgia, 'Times New Roman', 'Book Antiqua', serif;
  --cc-brass: #c9a24a; --cc-brass-dark: #7a5a1e; --cc-parchment: #f6ead0; --cc-parchment-dark: #e2cc9c; --cc-ink: #3a2a16;
  position: fixed; inset: 0; z-index: 255; color: #fff; font-family: var(--cc-serif);
  display: flex; flex-direction: column; justify-content: space-between; align-items: center; overflow-y: auto;
  padding: calc(env(safe-area-inset-top, 0px) + 72px) 16px calc(env(safe-area-inset-bottom, 0px) + 24px);
  background: linear-gradient(180deg, rgba(40, 24, 48, 0.5) 0%, rgba(40, 24, 48, 0.1) 30%, rgba(30, 20, 30, 0) 44%,
    rgba(30, 20, 18, 0.45) 66%, rgba(24, 16, 12, 0.82) 100%);
}
/* soft sun rays from the top corner: a few faint warm wedges, drawn once */
.cc-main-rays {
  position: absolute; inset: 0; pointer-events: none; opacity: 0.55;
  background:
    radial-gradient(circle at 85% 4%, rgba(255, 236, 190, 0.6) 0, rgba(255, 210, 140, 0.2) 16%, rgba(255, 190, 120, 0) 42%),
    repeating-conic-gradient(from 200deg at 85% 4%, rgba(255, 225, 170, 0.14) 0deg 5deg, rgba(255, 225, 170, 0) 5deg 15deg);
  -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.6) 40%, transparent 70%);
  mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.6) 40%, transparent 70%);
}
.cc-main-head { position: relative; text-align: center; width: 100%; max-width: 440px; }
/* I (owner 2026-10-17, poster approved): the Bloc Nation poster fills the screen behind the menu, from its top so its
   painted title stays in view; the shade under the cards keeps them legible. The poster carries the title, so the text
   title is kept for screen readers only, and the tagline sits under the painted title. */
.cc-main-poster {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center top;
  pointer-events: none; user-select: none;
}
.cc-main-shade {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(20, 14, 8, 0) 0%, rgba(20, 14, 8, 0) 45%, rgba(20, 14, 8, 0.35) 65%, rgba(20, 14, 8, 0.75) 100%);
}
.cc-main-poster ~ .cc-main-head .cc-main-title {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
.cc-main-poster ~ .cc-main-head .cc-main-tagline { margin-top: max(0px, calc(min(19vh, 34vw) - 72px)); }
/* the title: carved gold lettering with a brass edge and a dark outline */
.cc-main-title {
  margin: 0; font-weight: 700; letter-spacing: 0.06em; line-height: 0.95; font-family: var(--cc-serif);
  font-size: clamp(2.6rem, min(14vw, 9vh), 4.6rem); color: #ffe08a;
  -webkit-text-stroke: 1.5px #4a3210;
  text-shadow: 0 2px 0 #c9a24a, 0 4px 0 #8a6420, 0 6px 0 #4a3210, 0 10px 22px rgba(0, 0, 0, 0.6);
}
/* the tagline on a small ribbon */
.cc-main-tagline {
  display: inline-block; margin: 14px 0 0; padding: 6px 18px; border-radius: 4px;
  font-size: clamp(0.9rem, 3.6vw, 1.1rem); font-style: italic; font-weight: 700; color: #fff8e6;
  background: linear-gradient(180deg, #3f8a4c, #2b6638); border: 2px solid var(--cc-brass);
  box-shadow: 0 3px 0 var(--cc-brass-dark), 0 6px 14px rgba(0, 0, 0, 0.4);
}
.cc-main-cards { position: relative; width: 100%; max-width: 440px; display: flex; flex-direction: column; gap: 14px; }
.cc-main-note { margin: 0; font-size: 14px; color: #ffe08a; text-shadow: 0 1px 3px #000; }
/* a card: parchment in a brass frame (an outer brass border, an inner hairline, a pressed brass lip below) */
.cc-card {
  position: relative; min-height: 72px; width: 100%; padding: 12px 16px 12px 72px; border-radius: 14px; text-align: left;
  font-family: var(--cc-serif); font-size: 1.3rem; font-weight: 700; letter-spacing: 0.02em; color: var(--cc-ink);
  background: linear-gradient(180deg, var(--cc-parchment) 0%, #efdfba 60%, var(--cc-parchment-dark) 100%);
  border: 3px solid var(--cc-brass);
  box-shadow: inset 0 0 0 2px rgba(255, 248, 225, 0.7), inset 0 0 0 3px rgba(122, 90, 30, 0.35),
    0 5px 0 var(--cc-brass-dark), 0 10px 20px rgba(0, 0, 0, 0.4);
  touch-action: manipulation; -webkit-tap-highlight-color: transparent; cursor: pointer;
}
.cc-card:active { transform: translateY(3px); box-shadow: inset 0 0 0 2px rgba(255, 248, 225, 0.7), 0 2px 0 var(--cc-brass-dark), 0 6px 12px rgba(0, 0, 0, 0.4); }
/* Solo: the banner card, in the green of the next-step ribbon */
.cc-card-primary {
  min-height: 88px; font-size: 1.6rem; color: #fff8e6;
  background: linear-gradient(180deg, #4f9f5c 0%, #3a8247 55%, #2b6638 100%);
  box-shadow: inset 0 0 0 2px rgba(255, 240, 190, 0.45), 0 6px 0 var(--cc-brass-dark), 0 12px 24px rgba(0, 0, 0, 0.45);
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.35);
}
.cc-card-primary:active { box-shadow: inset 0 0 0 2px rgba(255, 240, 190, 0.45), 0 3px 0 var(--cc-brass-dark), 0 6px 12px rgba(0, 0, 0, 0.45); }
.cc-card-held { color: rgba(58, 42, 22, 0.85); }
.cc-card-held .cc-card-sub { color: #9a4a1a; font-style: italic; }
.cc-card-sub { display: block; margin-top: 4px; font-size: 0.85rem; font-weight: 400; letter-spacing: 0; color: rgba(58, 42, 22, 0.85); }
.cc-card-primary .cc-card-sub { color: #eaf7e4; text-shadow: none; }
/* the icon sits in a round brass medallion */
.cc-card-icon {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%); box-sizing: content-box; padding: 6px;
  border-radius: 50%; color: #7a4f1c; background: radial-gradient(circle at 35% 30%, #fff3cf, #e0c27c 70%, #b58a38);
  border: 2px solid var(--cc-brass-dark);
}
.cc-card-primary .cc-card-icon { color: #2b6638; }
/* landscape on a phone: the title on the left, the cards on the right, all of it on one screen */
@media (orientation: landscape) and (max-height: 600px) {
  .cc-main {
    flex-direction: row; justify-content: center; align-items: center; gap: 32px;
    padding: calc(env(safe-area-inset-top, 0px) + 16px) calc(env(safe-area-inset-right, 0px) + 24px)
      calc(env(safe-area-inset-bottom, 0px) + 16px) calc(env(safe-area-inset-left, 0px) + 24px);
    background: linear-gradient(90deg, rgba(40, 24, 48, 0.45) 0%, rgba(30, 20, 30, 0.05) 40%, rgba(30, 20, 18, 0.5) 62%, rgba(24, 16, 12, 0.8) 100%);
  }
  .cc-main-head { flex: 1 1 0; max-width: 420px; }
  .cc-main-title { font-size: clamp(2.2rem, 13vh, 4rem); }
  /* I: on its side the whole poster stands at the left, full height (title and all in view), the cards to its right */
  .cc-main { background: #2a2418; }
  .cc-main-poster { width: auto; right: auto; left: env(safe-area-inset-left, 0px); object-fit: contain; }
  .cc-main-shade { background: linear-gradient(90deg, rgba(20, 14, 8, 0) 40%, rgba(20, 14, 8, 0.6) 100%); }
  .cc-main-poster ~ .cc-main-head { opacity: 0; } /* still read by a screen reader */
  .cc-main-cards { flex: 0 1 360px; gap: 10px; }
  .cc-card { min-height: 56px; }
  .cc-card-primary { min-height: 64px; }
}

/* Game modes: the mode step (components/GameMenu.tsx ModeMenu) reuses the main menu's parchment cards, smaller */
.cc-modes-title { font-size: clamp(2rem, min(11vw, 7vh), 3.4rem); }
.cc-card-mode { min-height: 64px; font-size: 1.15rem; }
.cc-card-mode.cc-card-primary { min-height: 64px; font-size: 1.15rem; }
.cc-card-mode[aria-pressed='true'] { outline: 3px solid #ffd54a; outline-offset: 2px; }
.cc-card-back { min-height: 48px; padding-left: 16px; text-align: center; font-size: 1.05rem; }
@media (orientation: landscape) and (max-height: 600px) {
  .cc-card-mode, .cc-card-mode.cc-card-primary { min-height: 48px; }
  .cc-card-mode .cc-card-sub { font-size: 0.75rem; }
}

#root {
  width: 100%;
  height: 100dvh;
  max-width: calc(100dvh * 9 / 16);
  position: relative;
  overflow: hidden;
  background: #87CEEB;
}
/* civLook.css — THE ONE SHARED LOOK of every Bloc Nation button, panel and HUD piece (owner, 2026-10-16: "make the buttons
   more stylized ... give them a 3d look and a civ VI look"; "all the menu options should be in civilization style and not
   minecraft style"). Civilization V and VI are the inspiration only; nothing is copied. Drawn with CSS alone: gradients,
   inset and outer shadows, no images and no blur filters (a blur over the WebGL canvas costs every frame on a phone).

   How it applies everywhere without touching each component's behaviour or hit areas:
   - the face is the serif --cv-serif (components use 'var(--cv-serif)' in place of the old monospace);
   - every button inside a panel ([role=dialog], [role=alertdialog] or .cv-ui) gets the bevel: a top highlight and a
     bottom shade laid OVER its own colour (background-image), a brass rim (border-color, never the border width) and a
     raised lip below (box-shadow). Its colour (green go, red danger, quiet, a chip that is on) stays its own, and
     nothing that sets size or position changes, so every tap area is what it was;
   - pressed, it sinks: 2 px down and the lip shrinks;
   - panels themselves are deep Civ-blue lacquer with a brass inner frame (--cv-sheet-bg + .cv-ui framing);
   - the in-game HUD (ribbon, plaques, tags, medallions, the quick-bar frame) uses the cv-* classes below. */
:root {
  --cv-serif: Georgia, 'Times New Roman', 'Book Antiqua', serif;
  --cv-brass: #c9a24a;
  --cv-brass-light: #ecd28a;
  --cv-brass-dark: #7a5a1e;
  --cv-ink: #3a2a16;
  --cv-parchment: #f6ead0;
  --cv-parchment-dark: #e2cc9c;
  --cv-green: #3a8247;
  /* owner 2026-10-17 (ui/costTone.mjs TONES): an ingredient the bag covers reads green; one it lacks stays gold. --cv-ok
     on the dark panels (8.8:1 on #142a38), --cv-ok-ink on parchment (5.6:1 on #f6ead0): WCAG AA on both. */
  --cv-ok: #7ddc88;
  --cv-ok-ink: #1d6a2a;
  --cv-short: #ffcf5a;
  --cv-sheet-bg: linear-gradient(180deg, rgba(18, 38, 52, 0.97) 0%, rgba(12, 26, 38, 0.97) 60%, rgba(9, 19, 28, 0.98) 100%);
  --cv-card-bg: linear-gradient(180deg, #1d3a4c 0%, #142a38 100%);
  --cv-bevel: linear-gradient(180deg, rgba(255, 255, 255, 0.28) 0%, rgba(255, 255, 255, 0.06) 42%, rgba(0, 0, 0, 0) 58%, rgba(0, 0, 0, 0.22) 100%);
  --cv-raised: inset 0 1px 0 rgba(255, 250, 225, 0.45), inset 0 -2px 0 rgba(0, 0, 0, 0.3), 0 3px 0 var(--cv-brass-dark), 0 5px 10px rgba(0, 0, 0, 0.45);
  --cv-pressed: inset 0 1px 0 rgba(255, 250, 225, 0.25), inset 0 2px 4px rgba(0, 0, 0, 0.35), 0 1px 0 var(--cv-brass-dark), 0 2px 4px rgba(0, 0, 0, 0.4);
}

/* ---- panels and menus ---- */
[role='dialog'], [role='alertdialog'], .cv-ui { font-family: var(--cv-serif) !important; }
[role='dialog'] h1, [role='dialog'] h2, .cv-ui h2 { font-family: var(--cv-serif); }

/* a full panel: a brass frame drawn inside its edge */
.cv-ui-frame, [role='dialog'].cc-menu:not(.cc-main), .cc-menu[role='alertdialog'] > div {
  box-shadow: inset 0 0 0 2px var(--cv-brass), inset 0 0 0 4px rgba(20, 12, 4, 0.55), inset 0 0 0 5px rgba(236, 210, 138, 0.25);
}

/* every button in a panel: raised, bevelled, brass-rimmed; its own colour shows through the bevel */
:is([role='dialog'], [role='alertdialog'], .cv-ui) button:not(.cc-card):not(.cv-flat),
.cv-btn {
  background-image: var(--cv-bevel) !important;
  border-color: var(--cv-brass) !important;
  box-shadow: var(--cv-raised) !important;
  font-family: var(--cv-serif) !important;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.55);
  transition: transform 60ms ease-out, box-shadow 60ms ease-out;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
:is([role='dialog'], [role='alertdialog'], .cv-ui) button:not(.cc-card):not(.cv-flat):active,
.cv-btn:active {
  transform: translateY(2px);
  box-shadow: var(--cv-pressed) !important;
}
:is([role='dialog'], [role='alertdialog'], .cv-ui) button:not(.cc-card):not(.cv-flat)[aria-pressed='true'] {
  border-color: var(--cv-brass-light) !important;
  box-shadow: inset 0 0 0 1px var(--cv-brass-light), var(--cv-raised) !important;
}
:is([role='dialog'], [role='alertdialog'], .cv-ui) button:disabled { box-shadow: none !important; transform: none; }

/* owner 2026-10-17: "the bag button should also be a solid button": the long Bag bar is an opaque parchment face under
   the bevel (.cv-btn sets background-image only, so without a colour the bar was see-through), never faded */
.cv-btn.cc-bag-bar {
  background-color: var(--cv-parchment) !important;
  opacity: 1 !important;
}

/* owner 2026-10-17 (ui/costTone.mjs): covered ingredients green, short ones gold; parchment takes the dark green */
.cv-ok { color: var(--cv-ok) !important; }
.cv-short { color: var(--cv-short) !important; }
.cv-plaque .cv-ok, .cv-tag .cv-ok, .cv-medal-parch .cv-ok { color: var(--cv-ok-ink) !important; }

/* owner, 2026-10-17 (ui/craftReady.mjs): a recipe the player can make RIGHT NOW glows in the Bag's Craft tab, the
   selected-glow colours of ui/selectGlow.mjs (a gold core, an aura fading through orange to red) over the raised lip,
   and breathes gently; with prefers-reduced-motion it holds still. One tap on it crafts. */
:is([role='dialog'], [role='alertdialog'], .cv-ui) button.cv-craft-ready:not(.cv-flat) {
  border-color: #ffcc40 !important;
  box-shadow: 0 0 0 2px #ffcc40, 0 0 10px 4px rgba(240, 128, 49, 0.6), 0 0 22px 5px rgba(224, 52, 34, 0.3), var(--cv-raised) !important;
  animation: cv-craft-breathe 1.1s ease-in-out infinite alternate;
}
@keyframes cv-craft-breathe { from { filter: brightness(1); } to { filter: brightness(1.18); } }
@media (prefers-reduced-motion: reduce) {
  :is([role='dialog'], [role='alertdialog'], .cv-ui) button.cv-craft-ready { animation: none !important; }
}

/* look pass 3: THE panel Close (ui/CloseButton.tsx): 48 px tall, 96 wide, the pause button's blue lacquer, 3D */
/* owner 2026-10-17: a round X (an SVG, no word), 52 px across (ui/hudLayout.mjs PANEL_CLOSE), docked under the HUD */
.cv-close {
  min-height: 52px; min-width: 52px; width: 52px; height: 52px; padding: 0; flex-shrink: 0; margin-left: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50% !important; border: 2px solid var(--cv-brass); background-color: #2a4a5e; color: #ffe9b0;
  cursor: pointer;
}

/* look pass 3: the bag's tabs (Items / Craft / Build) as raised Civ buttons; the open one green and gold-rimmed */
.cv-tab { flex: 1; min-height: 48px; border-radius: 10px; border: 2px solid var(--cv-brass); background-color: #1d3a4c; color: #f2e6c8; font-size: 15px; font-weight: 800; }
.cv-tab[aria-pressed='true'] { background-color: var(--cv-green); color: #fff8e6; }

/* text fields and the volume sliders */
:is([role='dialog'], .cv-ui) input:not([type='range']) { border-color: var(--cv-brass) !important; font-family: var(--cv-serif) !important; }
.cv-range {
  -webkit-appearance: none; appearance: none; width: 100%; height: 44px; margin: 0; background: transparent; touch-action: pan-y;
}
.cv-range::-webkit-slider-runnable-track {
  height: 10px; border-radius: 6px; border: 1px solid var(--cv-brass-dark);
  background: linear-gradient(90deg, var(--cv-brass) 0 var(--cv-fill, 50%), rgba(0, 0, 0, 0.45) var(--cv-fill, 50%) 100%);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.6);
}
.cv-range::-moz-range-track { height: 10px; border-radius: 6px; border: 1px solid var(--cv-brass-dark); background: rgba(0, 0, 0, 0.45); }
.cv-range::-moz-range-progress { height: 10px; border-radius: 6px; background: var(--cv-brass); }
.cv-range::-webkit-slider-thumb {
  -webkit-appearance: none; width: 30px; height: 30px; margin-top: -11px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff3cf, #e0c27c 60%, #a87e30); border: 2px solid var(--cv-brass-dark);
  box-shadow: 0 2px 0 var(--cv-brass-dark), 0 3px 6px rgba(0, 0, 0, 0.5);
}
.cv-range::-moz-range-thumb {
  width: 28px; height: 28px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff3cf, #e0c27c 60%, #a87e30);
  border: 2px solid var(--cv-brass-dark);
}

/* ---- the in-game HUD ---- */
/* parchment plaque in a brass frame (health and food, the item flash, the animal label) */
.cv-plaque, .cv-tag {
  font-family: var(--cv-serif); color: var(--cv-ink);
  background: linear-gradient(180deg, var(--cv-parchment) 0%, #efdfba 60%, var(--cv-parchment-dark) 100%);
  border: 2px solid var(--cv-brass); border-radius: 8px;
  box-shadow: inset 0 0 0 1px rgba(255, 248, 225, 0.7), 0 2px 0 var(--cv-brass-dark), 0 3px 8px rgba(0, 0, 0, 0.35);
}
.cv-tag { font-weight: 700; white-space: nowrap; text-shadow: none; }

/* the next-step ribbon: green, brass-edged, with notched ends */
.cv-ribbon {
  position: relative; font-family: var(--cv-serif); color: #fff8e6; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
  background: var(--cv-bevel), linear-gradient(180deg, #4f9f5c 0%, var(--cv-green) 55%, #2b6638 100%);
  border: 2px solid var(--cv-brass); border-radius: 6px;
  box-shadow: var(--cv-raised);
  transition: transform 60ms ease-out, box-shadow 60ms ease-out;
}
.cv-ribbon:active { transform: translateY(2px); box-shadow: var(--cv-pressed); }
.cv-ribbon.cv-ribbon-idle { background: var(--cv-bevel), linear-gradient(180deg, #2a4a5e 0%, #1c3444 100%); }
.cv-ribbon::before, .cv-ribbon::after {
  content: ''; position: absolute; top: 50%; width: 10px; height: 10px; background: var(--cv-brass);
  transform: translateY(-50%) rotate(45deg); box-shadow: 0 0 0 2px rgba(58, 42, 22, 0.6);
}
.cv-ribbon::before { left: -6px; }
.cv-ribbon::after { right: -6px; }

/* round medallions: HIT red, USE blue, the rest parchment; brass ring, raised face, pressed sinks */
.cv-medal {
  border-radius: 50%; font-family: var(--cv-serif); font-weight: 700; letter-spacing: 0.04em;
  border: 3px solid var(--cv-brass);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.35), inset 0 -4px 0 rgba(0, 0, 0, 0.28), 0 0 0 2px rgba(58, 42, 22, 0.55), 0 4px 0 var(--cv-brass-dark), 0 6px 12px rgba(0, 0, 0, 0.45);
  transition: transform 60ms ease-out, box-shadow 60ms ease-out;
}
.cv-medal:active {
  transform: translateY(3px) scale(0.97);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.35), 0 0 0 2px rgba(58, 42, 22, 0.55), 0 1px 0 var(--cv-brass-dark), 0 2px 5px rgba(0, 0, 0, 0.4);
}
.cv-medal-red { color: #fff4e0; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.6); background: radial-gradient(circle at 38% 30%, #e86a52 0%, #c0392b 48%, #7e1d14 100%); }
.cv-medal-blue { color: #f2f6ff; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.6); background: radial-gradient(circle at 38% 30%, #6fa3e6 0%, #2f66b8 50%, #173c78 100%); }
.cv-medal-parch { color: var(--cv-ink); background: radial-gradient(circle at 38% 30%, #fffaf0 0%, var(--cv-parchment) 45%, var(--cv-parchment-dark) 100%); }
.cv-medal-gold { color: var(--cv-ink); background: radial-gradient(circle at 38% 30%, #fff3cf 0%, #e9c46a 50%, #a87e30 100%); }

/* the quick bar: a dark brass frame, sunken slots */
.cv-frame {
  background: linear-gradient(180deg, #3a2c18 0%, #241a0e 100%);
  border: 2px solid var(--cv-brass); border-radius: 10px;
  box-shadow: inset 0 0 0 1px rgba(236, 210, 138, 0.3), 0 3px 0 var(--cv-brass-dark), 0 5px 12px rgba(0, 0, 0, 0.45);
}
.cv-slot {
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.35), rgba(255, 255, 255, 0.04));
  border: 1px solid rgba(201, 162, 74, 0.55); border-radius: 6px; box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.5);
}

/* the arcade exit (the shared shell's button, drawn by _shell/arcade-hud.js): framed to match the pause button */
button[data-arcade-exit] {
  background: var(--cv-bevel), linear-gradient(180deg, #2a4a5e, #1c3444) !important;
  border: 2px solid var(--cv-brass) !important;
  box-shadow: var(--cv-raised) !important;
  border-radius: 10px !important;
}
button[data-arcade-exit]:active { transform: translateY(2px); box-shadow: var(--cv-pressed) !important; }

@media (prefers-reduced-motion: reduce) {
  .cv-btn, .cv-medal, .cv-ribbon, :is([role='dialog'], .cv-ui) button { transition: none !important; }
}

/* owner 2026-10-17: "when a science is discovered the button should fill in with the tannish gold opaque civ 6 3d
   button feel with the svg icon lit to show its been researched". A discovered tech button (components/TechTree.tsx):
   opaque tan-gold, lighter at the top, bronze at the bottom (ui/techIcons.mjs DISCOVERED_LOOK; techIcons.test.mjs pins
   these values), a bronze rim, a soft inner top highlight and a small drop shadow: a pressed metal button. Static CSS,
   no images, no per-frame animation. Undiscovered, researching and available buttons keep their own looks. */
:is([role='dialog'], [role='alertdialog'], .cv-ui) button.cc-tech-discovered:not(.cc-card):not(.cv-flat) {
  background-color: #e9c46a !important;
  background-image: linear-gradient(180deg, #ecd28a 0%, #e9c46a 45%, #a87e30 100%) !important;
  border: 2px solid #7a5a1e !important;
  box-shadow: inset 0 2px 0 rgba(255, 248, 220, 0.75), inset 0 -2px 0 rgba(58, 42, 22, 0.45), 0 2px 0 #7a5a1e, 0 4px 7px rgba(0, 0, 0, 0.55) !important;
  opacity: 1 !important;
}
/* the lit glyph: a warm glow round its bright stroke (ui/TechMedallion.tsx) */
.cc-tech-icon-lit { filter: drop-shadow(0 0 1.5px rgba(255, 214, 110, 0.95)); }
/* the one-time fill-in when a tech completes with the chart open; runs once, then the class is dropped */
.cc-tech-fill-in { animation: cc-tech-fill-in 0.7s ease-out 1; }
@keyframes cc-tech-fill-in {
  from { transform: scale(1.14); filter: brightness(1.7); }
  to { transform: scale(1); filter: brightness(1); }
}
@media (prefers-reduced-motion: reduce) { .cc-tech-fill-in { animation: none; } }

/* The tech chart's current research PULSES and a selected star GLOWS (components/TechTree.tsx; owner 2026-10-15: "a
   selected star glows"). The panel bevel at the top of this file sets box-shadow !important on every dialog button: it
   beat the stars' inline glow, and (an !important declaration outranks a running CSS animation) froze the pulse. So
   each state has its own class rule, a class more specific than the bevel and later than it and .cc-tech-discovered
   (ui/techStars.test.mjs parses this file and checks both). The bevel rule itself is untouched for every other dialog.
   - selected: the select glow (ui/selectGlow.mjs glowBoxShadow), handed in by TechTree.tsx as --cc-star-glow;
   - researching: the pulse runs on a ring drawn by ::after, which no button rule reaches, so nothing !important can
     freeze it. Steady with prefers-reduced-motion. */
:is([role='dialog'], [role='alertdialog'], .cv-ui) button.cc-tech-selected:not(.cc-card):not(.cv-flat) {
  box-shadow: var(--cc-star-glow) !important;
}
:is([role='dialog'], [role='alertdialog'], .cv-ui) button.cc-tech-researching:not(.cc-card):not(.cv-flat)::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
  animation: cc-tech-pulse 1.6s ease-in-out infinite;
}
@keyframes cc-tech-pulse {
  0%, 100% { box-shadow: 0 0 6px 2px rgba(255, 213, 74, 0.55); }
  50% { box-shadow: 0 0 18px 7px rgba(255, 213, 74, 0.95); }
}
@media (prefers-reduced-motion: reduce) {
  :is([role='dialog'], [role='alertdialog'], .cv-ui) button.cc-tech-researching:not(.cc-card):not(.cv-flat)::after {
    animation: none;
    box-shadow: 0 0 12px 5px rgba(255, 213, 74, 0.85);
  }
}

/* the ribbon carousel's pager (components/NextStepLine.tsx, ui/ribbonLayout.mjs): its dots pulse softly while an urgent
   card waits (under attack, a city fallen, the annex / raze choice) */
@keyframes cv-pager-pulse { from { opacity: 0.55; transform: scale(1); } to { opacity: 1; transform: scale(1.35); } }
.cv-pager-pulse .cv-pager-dot { animation: cv-pager-pulse 0.9s ease-in-out infinite alternate; }
@media (prefers-reduced-motion: reduce) { .cv-pager-pulse .cv-pager-dot { animation: none; } }
