/* public.css: made by tools/build-public-css.mjs from style.css 3ff1ffcdc1bcf92c. Do not edit; edit style.css and run it again. */
/* =====================================================================
   CARD FORGE — style.css
   Application chrome only. Each card template carries its own embedded
   stylesheet (see script.js) so the exported PNG matches the preview.
   ===================================================================== */

/* ---------- Design tokens ---------- */
:root {
  --ui-bg: #0a0c11;
  --ui-bg-2: #0d1016;
  --ui-panel: #13161e;
  --ui-panel-2: #1a1e28;
  --ui-line: rgba(255, 255, 255, .065);
  --ui-line-2: rgba(255, 255, 255, .12);
  --ui-text: #e7eaf2;
  --ui-dim: #8c93a6;
  --ui-faint: #5d6478;
  --ui-accent: #8f9bff;
  --ui-accent-2: #38e1ff;
  --ui-gold: #e9b95c;
  --radius: 12px;
  --radius-sm: 7px;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --header-h: 56px;
  --ui-z: 1;                                  /* the editor's interface size, see "Interface size" */
  --card-glow: #00e5ff;

  /* Roles the chrome used to write as literal colours. Each has a light
     value below, which is all the light theme is. */
  --ui-strong: #ffffff;                       /* headings, pressed controls */
  --ui-hover-line: rgba(255, 255, 255, .2);   /* a border under the pointer */
  --ui-track: rgba(255, 255, 255, .1);        /* slider tracks, switches, meters */
  --ui-accent-hover: #a8b2ff;
  --ui-accent-soft: rgba(143, 155, 255, .12);
  --ui-accent-soft-2: rgba(143, 155, 255, .2);
  --ui-accent-text: #c9cfff;                  /* text on a soft accent */
  --ui-on-accent: #07080d;                    /* text on a solid accent */
  --ui-float: rgba(19, 22, 30, .88);          /* floating toolbars */
  --ui-scrim: rgba(4, 6, 11, .72);            /* behind a dialog */
  --ui-scrim-strong: rgba(6, 8, 13, .84);
  --ui-shadow: rgba(0, 0, 0, .5);
  --ui-shadow-strong: rgba(0, 0, 0, .75);
  --ui-scroll: #2a2f3c;
  --ui-stage-grid: rgba(255, 255, 255, .03);
  --ui-danger-text: #ffd7dd;
  --ui-danger-bg: rgba(244, 63, 94, .13);
  --ui-danger-line: rgba(244, 63, 94, .38);
  --ui-ok-text: #cfe9d6;
  --ui-ok-bg: rgba(74, 222, 128, .12);
  --ui-ok-line: rgba(74, 222, 128, .32);
  --ui-warn-text: #fde7b0;
  --ui-warn-bg: rgba(251, 191, 36, .1);
  --ui-warn-line: rgba(251, 191, 36, .3);
}

/* The light theme (theme.js sets data-theme on <html>). Only the editor's
   chrome changes: the card is artwork and looks the same either way. */
:root[data-theme="light"] {
  --ui-bg: #eef0f5;
  --ui-bg-2: #ffffff;
  --ui-panel: #ffffff;
  --ui-panel-2: #f1f3f8;
  --ui-line: rgba(20, 26, 48, .08);
  --ui-line-2: rgba(20, 26, 48, .15);
  --ui-text: #1b1f2c;
  --ui-dim: #555d72;
  --ui-faint: #646b80;
  --ui-accent: #5561e6;
  --ui-accent-2: #0a8fb0;
  --ui-gold: #8a5a0a;
  --ui-strong: #0d1020;
  --ui-hover-line: rgba(20, 26, 48, .28);
  --ui-track: rgba(20, 26, 48, .12);
  --ui-accent-hover: #4450d6;
  --ui-accent-soft: rgba(85, 97, 230, .09);
  --ui-accent-soft-2: rgba(85, 97, 230, .16);
  --ui-accent-text: #3440b8;
  --ui-on-accent: #ffffff;
  --ui-float: rgba(255, 255, 255, .94);
  --ui-scrim: rgba(24, 28, 44, .32);
  --ui-scrim-strong: rgba(236, 238, 245, .9);
  --ui-shadow: rgba(20, 26, 48, .14);
  --ui-shadow-strong: rgba(20, 26, 48, .22);
  --ui-scroll: #c7cbd6;
  --ui-stage-grid: rgba(20, 26, 48, .045);
  --ui-danger-text: #b4233c;
  --ui-danger-bg: rgba(244, 63, 94, .08);
  --ui-danger-line: rgba(220, 38, 76, .32);
  --ui-ok-text: #145c31;
  --ui-ok-bg: rgba(34, 160, 90, .09);
  --ui-ok-line: rgba(34, 160, 90, .3);
  --ui-warn-text: #8a5700;
  --ui-warn-bg: rgba(245, 170, 20, .12);
  --ui-warn-line: rgba(200, 140, 10, .32);
}

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--ui-bg);
  color: var(--ui-text);
  font: 14px/1.45 var(--font);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }

/* ---------- Scrollbars ---------- */
.panel { scrollbar-width: thin; scrollbar-color: var(--ui-scroll) transparent; }
.panel::-webkit-scrollbar { width: 8px; }
.panel::-webkit-scrollbar-thumb { background: var(--ui-scroll); border-radius: 8px; border: 2px solid var(--ui-bg-2); }

/* =====================================================================
   HEADER
   ===================================================================== */
/* flex:none — the product name is the one thing in this header that must
   never be cut. The template picker wraps instead; it is built to. */
.brand { display: flex; align-items: center; gap: 12px; flex: none; }
.brand-mark { width: 36px; height: 36px; flex: none; filter: drop-shadow(0 0 10px rgba(143, 155, 255, .35)); }
.brand .brand-name {
  display: block; margin: 0; font-size: 16px; font-weight: 800; letter-spacing: .32em;
  background: linear-gradient(90deg, #fff, #c9d0ff 60%, var(--ui-gold));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.brand p { margin: 2px 0 0; font-size: 11.5px; color: var(--ui-dim); }
/* The wordmark is wide and letter-spaced, and the header gained two account
   buttons. Without this it breaks across two lines and shoves the header
   taller; truncating is the better failure. */
/* The wordmark is wide and letter-spaced, and the header gained two account
   buttons. Truncating beats wrapping to a second line, which shoves the whole
   header taller. */
.brand .brand-name, .brand p { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.brand-text { min-width: 0; }
/* The tagline never fits the slimmer top bar. */

.segmented {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--ui-bg-2); border: 1px solid var(--ui-line); border-radius: 10px;
}
.seg-btn[aria-pressed="true"] {
  color: var(--ui-text); background: var(--ui-panel-2);
  box-shadow: inset 0 0 0 1px var(--ui-line-2), 0 2px 10px rgba(0, 0, 0, .45);
}

/* The auto margin lives here, not on .brand. On a flex:none brand it soaks
   up every spare pixel and squeezes the picker into a second row. */
/* The brand is a link back to the homepage; it should not look like body copy. */

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 36px; padding: 0 14px;
  border: 1px solid var(--ui-line-2); border-radius: 8px;
  background: var(--ui-panel); color: var(--ui-text);
  font-size: 13px; font-weight: 600; white-space: nowrap;
  transition: background-color .15s, border-color .15s, transform .1s, box-shadow .15s;
}
.btn:hover { background: var(--ui-panel-2); border-color: var(--ui-hover-line); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .4; cursor: not-allowed; }
.btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; }
/* One solid accent, as a professional tool has, rather than a gradient on
   every call to action. */
.btn-primary {
  border: 0; color: var(--ui-on-accent); font-weight: 700; letter-spacing: .01em;
  background: var(--ui-accent);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .16) inset, 0 6px 16px -8px var(--ui-accent);
}
.btn-primary:hover { background: var(--ui-accent-hover); border-color: transparent; }
.btn-primary.is-busy { opacity: .7; pointer-events: none; }
.btn-block { width: 100%; height: 44px; }
.btn-icon { width: 44px; padding: 0; height: 44px; }

.link-btn {
  border: 0; background: none; padding: 4px 0; margin-top: 2px;
  color: var(--ui-accent); font-size: 12.5px; font-weight: 600;
}
.link-btn:hover { text-decoration: underline; }

/* =====================================================================
   WORKSPACE LAYOUT
   ===================================================================== */
/* ---------- Control groups ----------
   Flat sections divided by a hairline, the way a professional tool's
   inspector reads, rather than a stack of glowing cards. */
.group {
  background: transparent;
  border: 0; border-bottom: 1px solid var(--ui-line);
  border-radius: 0;
  padding: 14px 16px 12px;
  margin: 0;
}

.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 11px; }
.field:last-child { margin-bottom: 2px; }
.field label, .label { font-size: 12px; font-weight: 600; color: var(--ui-dim); }
.hint { margin: 8px 0 12px; font-size: 12px; color: var(--ui-faint); line-height: 1.4; }

.input {
  width: 100%;
  background: var(--ui-bg); border: 1px solid var(--ui-line-2); border-radius: var(--radius-sm);
  padding: 8px 10px; outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.input:hover { border-color: var(--ui-hover-line); }
.input:focus { border-color: var(--ui-accent); box-shadow: 0 0 0 3px var(--ui-accent-soft-2); }
textarea.input { resize: vertical; min-height: 64px; line-height: 1.45; }
input[type="number"] { font-variant-numeric: tabular-nums; }

/* ---------- Upload ---------- */

/* ---------- Range sliders ---------- */
.step {
  width: 26px; height: 26px; flex: none;
  border: 1px solid var(--ui-line-2); border-radius: 6px; background: var(--ui-bg);
  color: var(--ui-dim); font-size: 15px; line-height: 1; padding: 0;
}
.step:hover { color: var(--ui-text); border-color: var(--ui-accent); }

/* ---------- Rarity chips ---------- */
.chip { position: relative; display: block; }
.chip input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.chip span {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  height: 32px; border-radius: 7px;
  border: 1px solid var(--ui-line-2); background: var(--ui-bg);
  font-size: 11px; font-weight: 700; letter-spacing: .06em; color: var(--ui-dim);
  transition: color .15s, border-color .15s, background-color .15s;
}
.chip span::before {
  content: ""; width: 7px; height: 7px; transform: rotate(45deg);
  background: var(--chip); box-shadow: 0 0 6px var(--chip);
}
.chip:hover span { color: var(--ui-text); }
.chip input:checked + span {
  color: var(--ui-strong); border-color: var(--chip);
  background: color-mix(in srgb, var(--chip) 16%, var(--ui-bg));
}
.chip input:focus-visible + span { outline: 2px solid var(--ui-accent); outline-offset: 2px; }

/* ---------- Type chips ---------- */

/* ---------- Stat rows ---------- */

/* ---------- Template picker ---------- */
.template-opt[aria-pressed="true"] { border-color: var(--ui-accent); background: var(--ui-accent-soft); box-shadow: inset 0 0 0 1px var(--ui-accent); }

/* ---------- Presets ---------- */
.preset {
  display: flex; flex-direction: column; gap: 7px; text-align: left;
  padding: 8px; border-radius: 9px;
  border: 1px solid var(--ui-line-2); background: var(--ui-bg);
  transition: border-color .15s, transform .1s;
}
.preset:hover { border-color: var(--ui-hover-line); }
.preset:active { transform: translateY(1px); }
.preset[aria-pressed="true"] { border-color: var(--ui-accent); box-shadow: inset 0 0 0 1px var(--ui-accent); }

/* ---------- Colour pickers ---------- */

/* ---------- Toggles ---------- */
.toggle {
  position: relative;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 0; cursor: pointer; font-size: 13px;
}
.toggle + .toggle { border-top: 1px solid var(--ui-line); }
/* The real checkbox, invisible, laid over the whole row: a click anywhere on it
   toggles, and it has a size to click at any interface zoom (a 1px box became
   0.8px under the compact size, and automation could not find a point on it). */
.toggle input { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.switch {
  position: relative; flex: none;
  width: 38px; height: 22px; border-radius: 22px;
  background: var(--ui-track); transition: background-color .2s;
}
.switch::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 16px; height: 16px; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .4); transition: transform .2s;
}
.toggle input:checked + .switch { background: var(--ui-accent); }
.toggle input:checked + .switch::after { transform: translateX(16px); }
.toggle input:focus-visible + .switch { outline: 2px solid var(--ui-accent); outline-offset: 2px; }

/* ---------- Export group ---------- */

/* =====================================================================
   STAGE / LIVE PREVIEW
   ===================================================================== */

/* ---------- Toast ---------- */
.toast {
  position: fixed; left: 50%; bottom: 24px; z-index: 50;
  transform: translate(-50%, 20px); opacity: 0; pointer-events: none;
  padding: 10px 16px; border-radius: 10px;
  /* Dark in both themes, as notifications usually are, so its text is set
     here rather than inherited from a page that may be light. */
  background: #1c2130; border: 1px solid rgba(255, 255, 255, .12); color: #eef0f6;
  box-shadow: 0 12px 30px var(--ui-shadow);
  font-size: 13px; font-weight: 600;
  transition: opacity .2s, transform .2s;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* =====================================================================
   RESPONSIVE
   ===================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; }
}


/* =====================================================================
   LAYOUT EDITOR (Stage 1)
   ===================================================================== */

/* ---------- Layer list ---------- */

/* ---------- Icon buttons (layers + inspector) ---------- */
.icon-btn {
  width: 30px; height: 30px; flex: none; padding: 0;
  display: inline-grid; place-items: center;
  border: 1px solid transparent; border-radius: 7px; background: transparent; color: var(--ui-dim);
  transition: color .12s, background-color .12s, border-color .12s;
}
.icon-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.icon-btn:hover { color: var(--ui-text); background: var(--ui-panel-2); }
.icon-btn[aria-pressed="true"] { color: var(--ui-strong); background: var(--ui-accent-soft-2); border-color: rgba(143, 155, 255, .45); }

/* ---------- Inspector ---------- */

/* ---------- Stage toolbar ---------- */
.tool {
  height: 32px; min-width: 32px; padding: 0 8px;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 0; border-radius: 7px; background: transparent; color: var(--ui-dim);
  font-size: 12.5px; font-weight: 600;
}
.tool svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.tool:hover:not(:disabled) { color: var(--ui-text); background: var(--ui-panel-2); }
.tool:disabled { opacity: .35; cursor: not-allowed; }
.tool[aria-pressed="true"] { color: var(--ui-strong); background: var(--ui-accent-soft-2); }

/* ---------- Card editing states ---------- */
/* D1: layers hold still while something is being edited, or the handles would drift off them */

/* ---------- Selection overlay (never exported) ---------- */

@media (max-width: 760px) {
  .tool { height: 36px; min-width: 36px; }
}

/* ---------- Stage 2: text styling controls ---------- */

/* The text panel toggles rows that carry .field / .row-2 / .insp-range,
   whose explicit `display` would otherwise outrank the UA's [hidden]
   rule and leave them on screen. */
[hidden] { display: none !important; }

select.input {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 26px;
  background-image: linear-gradient(45deg, transparent 50%, var(--ui-dim) 50%), linear-gradient(135deg, var(--ui-dim) 50%, transparent 50%);
  background-position: calc(100% - 15px) 52%, calc(100% - 10px) 52%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

.input.color {
  padding: 2px;
  height: 32px;
  width: 100%;
  cursor: pointer;
  background: var(--ui-bg);
}
.input.color::-webkit-color-swatch-wrapper { padding: 0; }
.input.color::-webkit-color-swatch { border: 0; border-radius: 4px; }
.input.color::-moz-color-swatch { border: 0; border-radius: 4px; }

/* ---------- Stage 3: design tab ---------- */
/* ---------- Add tab ---------- */

/* ---------- Folding sections ---------- */
.group.is-folded .group-toggle svg { transform: rotate(0deg); }
.group.is-folded { padding-bottom: 14px; }
.group.is-folded > .group-title { margin-bottom: 0; }
.group.is-folded > :not(.group-title) { display: none !important; }

/* ---------- Stage 4: gradient stops and eyedropper ---------- */

/* ---------- Custom fields ---------- */
/* the arrow needs its own room, or "Paragraph" runs underneath it */

/* ---------- Accounts ---------- */
.auth-slot { display: flex; align-items: center; gap: 8px; }
.auth-gate {
  position: fixed; inset: 0; z-index: 60; display: grid; place-items: center;
  padding: 24px; background: var(--ui-scrim-strong); backdrop-filter: blur(10px);
}
.auth-gate[hidden] { display: none !important; }
.auth-gate-card {
  width: min(400px, 100%); padding: 30px 28px 24px; text-align: center;
  background: var(--ui-panel); border: 1px solid var(--ui-line); border-radius: 16px;
  box-shadow: 0 30px 80px var(--ui-shadow-strong);
}
.auth-gate-card .brand-mark { width: 44px; height: 44px; margin-bottom: 14px; }
.auth-gate-card h2 { margin: 0 0 10px; font-size: 21px; font-weight: 750; color: var(--ui-strong); }
.auth-gate-card > p { margin: 0 0 20px; font-size: 13.5px; line-height: 1.6; color: var(--ui-dim); }
.auth-gate-actions { display: flex; flex-direction: column; gap: 8px; }
.auth-gate-card .hint { margin: 16px 0 0; }
.auth-gate-card .hint a { color: var(--ui-dim); text-decoration: none; }
.auth-gate-card .hint a:hover { color: var(--ui-text); text-decoration: underline; }
body.is-locked { overflow: hidden; }
.auth-google { display: flex; justify-content: center; margin-bottom: 4px; }
.auth-or {
  display: flex; align-items: center; gap: 10px;
  margin: 14px 0 16px; font-size: 11.5px; color: var(--ui-faint);
}
.auth-or::before, .auth-or::after { content: ""; flex: 1; height: 1px; background: var(--ui-line); }
.auth-modal { max-width: 420px; }
.auth-form { padding: 16px 18px 18px; }
.auth-form .toggle { margin: 4px 0 12px; }
.auth-pass { position: relative; display: flex; align-items: center; }
.auth-pass .input { flex: 1; padding-right: 42px; }
.auth-pass .icon-btn { position: absolute; right: 4px; width: 32px; height: 32px; border: 0; background: none; }
.auth-error {
  margin: 0 0 12px; padding: 9px 11px; font-size: 12.5px; line-height: 1.45;
  color: var(--ui-danger-text); background: var(--ui-danger-bg);
  border: 1px solid var(--ui-danger-line); border-radius: 8px;
}
.auth-swap { margin: 12px 0 0; font-size: 12.5px; color: var(--ui-faint); text-align: center; }
.auth-swap[hidden] { display: none !important; }
.auth-notice {
  margin: 0 0 12px; padding: 9px 11px; font-size: 12.5px; line-height: 1.45;
  color: var(--ui-ok-text); background: var(--ui-ok-bg);
  border: 1px solid var(--ui-ok-line); border-radius: 8px;
}
.auth-note { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--ui-line); }
.acct { display: flex; align-items: center; gap: 8px; }
.acct-dot {
  width: 28px; height: 28px; flex: none; display: grid; place-items: center;
  border-radius: 50%; font-size: 12px; font-weight: 700; color: #0b0e16;
  background: linear-gradient(135deg, #8fe9ff, #8f9bff 60%, #c9a6ff);
}
.acct-name { font-size: 12.5px; font-weight: 600; color: var(--ui-text); max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.has-overlay { overflow: hidden; }

/* ---------- AI assist ---------- */
.linkish {
  padding: 0; border: 0; background: none; font: inherit; font-size: 12px; font-weight: 600;
  color: var(--ui-accent); cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.linkish:hover { color: var(--ui-text); }

/* ---------- Looks and the restore notice ---------- */
.look {
  display: flex; align-items: center; gap: 9px; text-align: left;
  padding: 8px; border: 1px solid var(--ui-line-2); border-radius: 10px;
  background: var(--ui-bg); color: var(--ui-text);
  transition: border-color .15s, background-color .15s;
}
.look:hover { border-color: var(--ui-accent); background: var(--ui-panel-2); }
.look[aria-pressed="true"] { border-color: var(--ui-accent); box-shadow: inset 0 0 0 1px var(--ui-accent); }

/* ---------- Card library ---------- */
body.modal-open { overflow: hidden; }
.overlay {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center;
  padding: 24px;
  background: var(--ui-scrim);
  backdrop-filter: blur(3px);
}
.modal {
  width: min(1040px, 100%); max-height: min(84vh, 820px);
  display: flex; flex-direction: column;
  background: var(--ui-bg-2);
  border: 1px solid var(--ui-line-2); border-radius: var(--radius);
  box-shadow: 0 30px 80px -20px var(--ui-shadow-strong);
}
.modal-head {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px; border-bottom: 1px solid var(--ui-line);
}
.modal-head h2 { margin: 0; font-size: 14px; font-weight: 700; }
.modal-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.modal-actions .icon-btn { width: 36px; height: 36px; }
.btn.is-busy { opacity: .6; pointer-events: none; }

@media (max-width: 620px) {
  .overlay { padding: 10px; }
  .modal-head { flex-wrap: wrap; }
  .modal-actions { width: 100%; margin-left: 0; }
  .modal-actions .btn { flex: 1; }
}

/* ---------- Zoom and pan ---------- */
/* Zoomed, the card must be redrawn at the new size, not a snapshot of it
   stretched: the tilt's 3D layer (will-change, preserve-3d, perspective) is
   rasterised once at 100%, and at 800% every edge was a block of pixels. */

/* ---------- Swatches for the three later templates ---------- */

/* The picker only shows on phones now (see the header rules): twelve buttons
   wrapped to four rows there, so it is one row that scrolls sideways. A scroll
   container's minimum width is zero, so it cannot widen the header. */

/* Shape tiles read better with a little breathing room than emblems do. */

/* The "picked up where you left off" bar takes a row of its own, so the card
   gives up that height while it shows. Without this the toolbar was pushed
   35px under the header on every screen up to about 1080px tall. */

/* ---------- Several layers selected ---------- */

/* ---------- Effects panel ---------- */

/* ---------- Precise layout ---------- */
.ruler { position: absolute; z-index: 3; touch-action: none; cursor: crosshair; border-radius: 3px; }
.pivot-grid button[aria-pressed="true"] { border-color: var(--ui-accent); }
.pivot-grid button[aria-pressed="true"]::after { background: var(--ui-accent); }
#el-lock[aria-pressed="true"] { color: var(--ui-accent); font-weight: 700; }

/* ---------- Drawing ---------- */
#btnPen[aria-pressed="true"], .add-btn[aria-pressed="true"] { color: var(--ui-text); background: color-mix(in srgb, var(--ui-accent-2) 16%, transparent); border-color: var(--ui-accent-2); }

/* ---------- Data-driven fields (13n) ---------- */

/* ---------- Reuse: templates, components, faces (13o) ---------- */

/* ---------- Production dialog (13p) ---------- */
.modal-prod { width: min(760px, calc(100vw - 32px)); }
.prod-tabs button[aria-selected="true"] { background: var(--ui-panel-2); color: var(--ui-text); border-color: var(--ui-accent); }
.modal-prod .modal-head { position: relative; padding-right: 64px; flex-wrap: wrap; }
.modal-prod .modal-actions { position: absolute; top: 50%; right: 16px; transform: translateY(-50%); }
@media (max-width: 520px) { .modal-prod .modal-actions { top: 14px; transform: none; } }
.modal-prod .modal-actions { width: auto; left: auto; margin: 0; }

/* ---------- Textures and symbols (13q) ---------- */

/* ---------- Selling: PSD and previews (13r) ---------- */
@media (max-width: 520px) {
  .modal-prod .row-3 { grid-template-columns: 1fr; }
}

/* ---------- Card back designs ---------- */
.back-tile[aria-pressed="true"] { border-color: var(--ui-accent); box-shadow: 0 0 0 1px var(--ui-accent); }
/* The Front/Back pair filled the stage toolbar at phone width: let it wrap
   (Done appears when a layer is selected), and keep the View menu's popover
   on screen by anchoring it to the right edge instead of centring it. */
/* Long labels in two-column rows wrap rather than widening the whole
   phone layout: 1fr alone cannot shrink below its content. */

/* ---------- Element art ---------- */   /* or a tall (5:7) picture stretches its square */

/* Rarity and element looks */

/* Custom stats */

/* ---------- Plans: badges, the account menu, upgrades ----------
   Shared by the editor, the homepage and the account page. A plan's colour:
   Free is neutral, Pro the accent, Studio gold. */
.plan-badge {
  display: inline-flex; align-items: center; height: 17px; padding: 0 6px; margin-left: 2px;
  border-radius: 20px; font-size: 9.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: #07080d; background: linear-gradient(135deg, #a3f5ff, #8f9bff); vertical-align: middle; flex: none;
}
.is-locked .plan-badge { box-shadow: 0 0 0 1px rgba(255, 255, 255, .15) inset; }
.btn.is-locked { position: relative; }

.toggle > span .plan-badge { background: linear-gradient(135deg, #f6dc9a, #e9b95c); }

.plan-chip {
  display: inline-flex; align-items: center; height: 20px; padding: 0 8px; border-radius: 20px;
  font-size: 10.5px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap;
  color: var(--ui-dim); border: 1px solid var(--ui-line-2); background: var(--ui-panel);
}
.plan-chip.plan-pro { color: #07080d; border-color: transparent; background: linear-gradient(135deg, #a3f5ff, #8f9bff); }
.plan-chip.plan-studio { color: #1a1204; border-color: transparent; background: linear-gradient(135deg, #f6dc9a, #e9b95c); }

.acct { position: relative; }
.acct-btn {
  display: flex; align-items: center; gap: 8px; height: 40px; padding: 0 10px 0 6px;
  border: 1px solid var(--ui-line-2); border-radius: 22px; background: var(--ui-panel);
  color: var(--ui-text); cursor: pointer; font: inherit;
}
.acct-btn:hover, .acct-btn[aria-expanded="true"] { border-color: var(--ui-hover-line); background: var(--ui-panel-2); }
.acct-dot.has-pic { padding: 0; overflow: hidden; background: var(--ui-panel-2); }
.acct-dot.has-pic img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* The editor header has no room for a name: picture and plan only. */
[data-auth-compact] .acct-btn .acct-name { display: none; }
[data-auth-compact] .acct-btn { padding-right: 8px; }
/* Just above the phone layout the header is at its fullest: the picture alone. */
@media (min-width: 761px) and (max-width: 880px) { [data-auth-compact] .acct-btn .plan-chip { display: none; } }
.acct-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 70; width: 264px;
  padding: 6px; border: 1px solid var(--ui-line-2); border-radius: 12px;
  background: var(--ui-bg-2); box-shadow: 0 24px 60px -12px var(--ui-shadow-strong);
}
.acct-menu[hidden] { display: none; }
.acct-menu-head { display: flex; align-items: center; gap: 10px; padding: 8px 8px 10px; border-bottom: 1px solid var(--ui-line); margin-bottom: 4px; }
.acct-menu-head .acct-dot { width: 34px; height: 34px; font-size: 14px; }
.acct-menu-head span { display: flex; flex-direction: column; min-width: 0; }
.acct-menu-head strong { font-size: 13px; color: var(--ui-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-menu-head small { font-size: 11.5px; color: var(--ui-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%;
  padding: 9px 10px; border: 0; border-radius: 8px; background: none; text-align: left;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--ui-text); text-decoration: none; cursor: pointer;
}
.acct-item span { font-size: 11px; font-weight: 600; color: var(--ui-faint); }
.acct-item:hover, .acct-item:focus-visible { background: var(--ui-panel-2); outline: none; }
.acct-upgrade { color: var(--ui-accent); }
/* A demo visit (api/demo.php): the chip, the time left, and what it means. */
.plan-chip.plan-demo { color: var(--ui-on-accent); border-color: transparent; background: var(--ui-accent); }
.demo-btn { padding: 0 12px 0 8px; }
.demo-left { font-size: 12px; font-weight: 600; color: var(--ui-dim); white-space: nowrap; font-variant-numeric: tabular-nums; }
@media (max-width: 880px) { .demo-btn .demo-left { display: none; } .demo-btn { padding: 0 8px; } }
.acct-note { margin: 2px 4px 6px; padding: 8px 10px; font-size: 12px; line-height: 1.45; color: var(--ui-dim); }
.is-demo-off { opacity: .55; }
.is-demo-off:hover { opacity: .75; }
.acct-warn { margin: 4px 4px 6px; padding: 8px 10px; font-size: 12px; line-height: 1.45; color: var(--ui-warn-text); background: var(--ui-warn-bg); border: 1px solid var(--ui-warn-line); border-radius: 8px; }

/* The upgrade dialog. */

/* "Your plan changed: reload". */
.plan-bar {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); z-index: 80;
  display: flex; align-items: center; gap: 14px; max-width: calc(100vw - 32px);
  padding: 10px 10px 10px 16px; border: 1px solid var(--ui-line-2); border-radius: 12px;
  background: var(--ui-bg-2); box-shadow: 0 18px 50px -10px var(--ui-shadow-strong);
  font-size: 13px; color: var(--ui-text);
}

/* The plans table (pricing.js). */
.pricing-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 14px; }
.pricing-toggle { display: inline-flex; padding: 3px; border: 1px solid var(--ui-line-2); border-radius: 22px; background: var(--ui-bg); }
.pricing-toggle button {
  height: 30px; padding: 0 14px; border: 0; border-radius: 18px; background: none; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 700; color: var(--ui-dim);
}
.pricing-toggle button span { font-size: 11px; color: var(--ui-gold); }
.pricing-toggle button[aria-pressed="true"] { background: var(--ui-panel-2); color: var(--ui-text); }
.pricing-trial { margin: 0; }
.pricing-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.pricing-grid.is-two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.plan-card {
  display: flex; flex-direction: column; padding: 18px; border-radius: 14px;
  border: 1px solid var(--ui-line-2); background: var(--ui-panel);
}
.plan-card.is-highlight { border-color: color-mix(in srgb, var(--ui-accent) 60%, transparent); box-shadow: 0 0 0 1px color-mix(in srgb, var(--ui-accent) 35%, transparent) inset, 0 18px 44px -18px color-mix(in srgb, var(--ui-accent) 55%, transparent); }
.plan-card.is-current { border-color: var(--ui-ok-line); }
.plan-card header { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 22px; }
.plan-card h3 { margin: 0; font-size: 16px; font-weight: 800; color: var(--ui-strong); }
.plan-flag { font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--ui-accent); }
.plan-price { margin: 12px 0 2px; display: flex; align-items: baseline; gap: 6px; }
.plan-price strong { font-size: 30px; font-weight: 800; letter-spacing: -.02em; color: var(--ui-strong); font-variant-numeric: tabular-nums; }
.plan-price span { font-size: 13px; color: var(--ui-faint); }
.plan-sub { margin: 0 0 12px; min-height: 18px; font-size: 12.5px; color: var(--ui-faint); }
.plan-card ul { flex: 1; margin: 0 0 16px; padding: 0; list-style: none; }
.plan-card li { position: relative; padding: 5px 0 5px 22px; font-size: 13px; line-height: 1.45; color: var(--ui-dim); }
.plan-card li::before {
  content: ""; position: absolute; left: 3px; top: 10px; width: 9px; height: 5px;
  border-left: 2px solid var(--ui-accent); border-bottom: 2px solid var(--ui-accent); transform: rotate(-45deg);
}
.pricing-note { margin: 12px 0 0; min-height: 1em; font-size: 12.5px; color: var(--ui-ok-text); }
.pricing-note.is-bad { color: var(--ui-danger-text); }
@media (max-width: 760px) {
  .pricing-grid, .pricing-grid.is-two { grid-template-columns: minmax(0, 1fr); }
  .acct-menu { position: fixed; top: 64px; right: 12px; left: auto; }
}

/* =====================================================================
   THE EDITOR SHELL (U1)
   A rail of sections on the left with one panel beside it, the card in
   the middle, and on the right the properties of whatever is selected, or
   of the card as a whole when nothing is. The top bar carries the card's
   name, a card menu, undo and redo, the library and export.

     >= 1024px   rail | panel | stage | properties   (the panel can hide)
     761-1023    rail | stage | properties, the panel slides over the stage
     <= 760      one column: stage, properties, rail as a row, panel
   ===================================================================== */

/* ---------- Top bar ---------- */
:root[data-theme="light"] .brand .brand-name { background: linear-gradient(90deg, #1b1f2c, #3440b8 60%, #b07516); -webkit-background-clip: text; background-clip: text; }

/* Export: the button downloads a PNG at the chosen size; its caret opens
   every other format and option. */
.split-caret[aria-expanded="true"] svg { transform: rotate(180deg); }

/* Menus: a <details> whose summary is the button. */
details.menu { position: relative; flex: none; }
details.menu > summary { list-style: none; }
details.menu > summary::-webkit-details-marker { display: none; }
.menu-pop {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 70;
  min-width: 240px; padding: 6px;
  background: var(--ui-bg-2); border: 1px solid var(--ui-line-2); border-radius: 12px;
  box-shadow: 0 24px 60px -12px var(--ui-shadow-strong);
}
.menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 10px; border: 0; border-radius: 8px; background: none; text-align: left;
  font-size: 13px; font-weight: 600; color: var(--ui-text);
}
a.menu-item { text-decoration: none; box-sizing: border-box; }
.menu-item svg { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; color: var(--ui-dim); }
.menu-item:hover, .menu-item:focus-visible { background: var(--ui-panel-2); outline: none; }
.menu-sep { height: 1px; margin: 6px 4px; background: var(--ui-line); }
.menu-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 6px 4px 4px 10px; font-size: 13px; font-weight: 600; color: var(--ui-dim); }
.theme-switch { display: inline-flex; gap: 2px; padding: 2px; border: 1px solid var(--ui-line-2); border-radius: 8px; background: var(--ui-bg); }
.theme-switch button {
  padding: 4px 9px; border: 0; border-radius: 6px; background: none;
  font-size: 12px; font-weight: 600; color: var(--ui-dim);
}
.theme-switch button:hover { color: var(--ui-text); }
.theme-switch button[aria-pressed="true"] { background: var(--ui-panel-2); color: var(--ui-strong); box-shadow: inset 0 0 0 1px var(--ui-line-2); }

/* ---------- The workspace grid ---------- */
.workspace {
  position: relative;
  height: calc(100vh - var(--header-h) * var(--ui-z));
  display: grid;
  grid-template-columns: calc(72px * var(--ui-z)) calc(320px * var(--ui-z)) minmax(0, 1fr) calc(316px * var(--ui-z));
  grid-template-rows: minmax(0, 1fr);
  grid-template-areas: "rail panel stage props";
}
.panel { overflow-y: auto; padding: 0; background: var(--ui-bg-2); }

/* ---------- The rail ---------- */
.rail-btn[aria-selected="true"] { color: var(--ui-strong); background: var(--ui-accent-soft); }
.rail-btn[aria-selected="true"] svg { color: var(--ui-accent); }
.workspace.panel-hidden .rail-btn[aria-selected="true"] { background: transparent; }
/* In a dialog's header it is a plain count beside the title, not the rail's corner badge. */
.modal-head .tab-count { position: static; align-self: center; }

/* ---------- Panel and properties headings ---------- */

/* Pieces that only exist on a phone (see the U11 block below). */

/* The properties panel shows one of two things. */
body.has-selection .props-insp { display: block; }
body.has-selection .card-props { display: none; }

/* ---------- The template gallery ---------- */
/* The rendered cards from the homepage, only fetched once the gallery is
   opened: a background in a hidden pane is never requested. */

/* My shapes and my gradients (E56) */
:root[data-theme="light"] .tpl-thumb.blank { background: repeating-linear-gradient(135deg, #e9ecf3 0 8px, #f3f5f9 8px 16px); outline-color: #aab0c2; }

/* ---------- The stage in both themes ---------- */
:root[data-theme="light"] .card-shadow { box-shadow: 0 34px 60px -22px rgba(20, 26, 48, .5), 0 10px 22px -10px rgba(20, 26, 48, .35); }
:root[data-theme="light"] .card-aura { opacity: .16; }

/* ---------- Narrower desktops ---------- */
@media (max-width: 1279px) {
  .workspace { grid-template-columns: calc(68px * var(--ui-z)) calc(290px * var(--ui-z)) minmax(0, 1fr) calc(290px * var(--ui-z)); }
}

/* Tablet: no room for the panel beside the card, so it slides over it. */
@media (min-width: 761px) and (max-width: 1023px) {
  .workspace {
    grid-template-columns: 64px minmax(0, 1fr) 280px;
    grid-template-areas: "rail stage props";
  }
  .workspace:not(.panel-open) .rail-btn[aria-selected="true"] { background: transparent; }
}

/* Phone (U11): the card stays on screen. The rail is a tab bar along the
   bottom; a section, or the properties of what is selected, opens as a sheet
   above it that can be dragged between half height, full height and closed,
   and the card shrinks to sit above a half-height sheet. setSheet() writes
   the sheet's height to --sheet-h and the part the card makes room for to
   --stage-cut, on :root so the toast can rise above the sheet too. */
@media (max-width: 760px) {
  :root { --header-h: 52px; --rail-h: 58px; --sheet-h: 0px; --stage-cut: 0px; --safe-b: env(safe-area-inset-bottom, 0px); }
  body { overflow: hidden; }

  /* One row: the mark, the card's name and its menu, undo and redo, export
     as an icon, the account. The library moved into the card menu. */

  .workspace { display: block; height: calc(100vh - var(--header-h)); height: calc(100dvh - var(--header-h)); }
  /* The toolbar stays at the top; the card is centred in what is left. */
  /* One row that scrolls sideways, never two. */

  /* The tab bar. */
  .workspace:not([data-sheet="panel"]) .rail .tab[aria-selected="true"] { background: transparent; color: var(--ui-dim); }
  .workspace:not([data-sheet="panel"]) .rail .tab[aria-selected="true"] svg { color: currentColor; }
  body.has-selection .rail-card .lbl-card { display: none; }
  body.has-selection .rail-card::after {
    content: ""; position: absolute; top: 7px; right: calc(50% - 16px);
    width: 7px; height: 7px; border-radius: 50%; background: var(--ui-accent);
  }

  /* The two sheets. */
  .workspace.is-sheet-dragging .panel-left, .workspace.is-sheet-dragging .panel-props { transition: none; }
  @keyframes sheet-up { from { transform: translateY(36px); opacity: .5; } }

  .toast { bottom: calc(var(--rail-h) + var(--safe-b) + var(--sheet-h) + 12px); }
  .menu-pop { position: fixed; top: calc(var(--header-h) + 4px); left: 8px; right: 8px; min-width: 0; }
  .step { width: 34px; height: 34px; }
}

/* The export panel's sections. */

/* ---------- Site content (13u) ---------- */
/* ---------- Set, attacks, card types (13v) ---------- */
/* ---------- Print proof (E40) ---------- */
/* ---------- Set statistics and the art search (13w) ---------- */

/* ---------- Pictures: Your uploads and Free pictures (Add tab) ---------- */
.seg-btn[aria-selected="true"] { background: var(--ui-panel-2); color: var(--ui-strong); box-shadow: inset 0 0 0 1px var(--ui-line-2); }
.pic-menu button[aria-current="true"] { color: var(--ui-accent-text); }

/* ---------- Brand kit (Design tab) ---------- */

/* ---------- Library: folders and storage ---------- */
.is-dragging-card .folder-chip[data-folder] { border-style: dashed; }

/* ---------- The font browser ---------- */
.gallery-link { margin-bottom: 12px; }

/* ---------- Publish to the gallery (editor) ---------- */
.gallery-publish { width: min(720px, calc(100vw - 32px)); max-height: calc(100vh - 48px); overflow: auto; }
.hint.is-warn { color: var(--ui-warn-text); }

/* ---------- Interface size ----------
   The editor's chrome (top bar, rail, panels, the card toolbar, its dialogs)
   is drawn at 80% on desktops unless "Large" is picked in the card menu
   (theme.js keeps the choice as data-ui-size on <html>). It is a CSS zoom on
   those areas, so every size inside them shrinks together, and the grid
   columns and the workspace height above multiply by --ui-z to match.
   The stage itself is never zoomed: the card's pointer maths (toCard, the
   handles, rulers, pinch) measures it, and must keep measuring real pixels.
   Phones and the tablet drawer keep their own sizes. */
@media (min-width: 1024px) {
  :root[data-ui-size="compact"], :root:not([data-ui-size]) { --ui-z: .8; }
   .workspace > .panel,
  body:has(> .workspace) .modal { zoom: var(--ui-z); }
}

/* Features for the local server only (video): never published, see script.js 13w. */

/* ---------- Play: deck, playtest table (E36), Tabletop Simulator (E37) ----------
   The table is positioned from pointer coordinates, so this dialog is never
   drawn at the compact interface zoom (see "Interface size"). */
body:has(> .workspace) .modal.modal-play { zoom: 1; }
.modal-play { width: min(1100px, 100%); height: min(860px, 100%); max-height: none; overflow: hidden; }
.modal-play .modal-head { flex-wrap: wrap; }
@media (max-width: 760px) {
  .modal-play { width: 100%; height: 100%; border-radius: 0; }
  .modal-play .modal-head { position: relative; padding-right: 60px; }
  .modal-play .modal-actions { position: absolute; top: 10px; right: 12px; left: auto; width: auto; margin: 0; }
}

/* ---------- Batch: a linked Google Sheet (E35) ---------- */

/* ---------- Shape builder (A9) ---------- */

/* ---------- Image trace (A14) and pattern maker (A17) ---------- */
.modal-trace, .modal-pattern { width: min(980px, calc(100vw - 32px)); }

/* ---------- Boards (A22) ----------
   The live card moves into the row, between the other boards, and every
   board is drawn at the live card's size. */
.board { display: flex; flex-direction: column; align-items: center; gap: 8px; flex: none; }

/* ---------- The Batch workspace ---------- */
.modal-batch { width: min(1280px, 100%); height: min(900px, 100%); max-height: none; overflow: hidden; }
.modal-batch .modal-head { flex-wrap: wrap; }
@keyframes bshimmer { to { background-position: -200% 0; } }
.btn.btn-sm { height: 30px; padding: 0 12px; font-size: 12.5px; }

/* ---------- Batch as a page (Editor | Batch) ---------- */
.mode-btn[aria-selected="true"] { background: var(--ui-bg-2); color: var(--ui-strong); box-shadow: 0 1px 3px var(--ui-shadow); }
.bp-steps button[aria-selected="true"] { border-color: var(--ui-accent); box-shadow: 0 0 0 2px var(--ui-accent-soft-2); }
.bp-steps button[aria-selected="true"] b { background: var(--ui-accent); color: var(--ui-on-accent); }
.bp-view .seg[aria-pressed="true"] { background: var(--ui-panel-2); color: var(--ui-strong); border-color: var(--ui-accent); }
/* The switch from 1024 px up; narrower, the card menu has Batch (the top bar is full there). */
#menuBatch { display: none; }
@media (max-width: 1023px) {
  #menuBatch { display: flex; }
}

/* ---------- The library as a page (N5): Editor | Library | Batch ---------- */
/* The switch from 1024 px up; narrower, the card menu has Library and Batch. */
#menuLibrary { display: none; }
@media (max-width: 1023px) {
  #menuLibrary { display: flex; }
}

/* ---------- Decks (T1) ---------- */

/* ---------- The binder (T2) ---------- */
/* The binder is an object, like the card: a leather binder lying open. Its
   pages follow the theme (black sleeves in the dark, white in the light);
   the leather is the cover colour the person picked. */
:root[data-theme="light"] .binder-view { --bd-page: #ecedf1; --bd-slot: #dfe1e7; --bd-edge: #fafafb; --bd-edge-line: #c3c6ce; --bd-ink: rgba(20, 22, 30, .62);
  --bd-ink-2: rgba(20, 22, 30, .38); --bd-flap: #ffffff; --bd-flap-2: #d8dae1; }
.pocket { position: relative; display: flex; flex-direction: column; gap: 5px; min-width: 0; }
/* The plastic sleeve: a lip along the opening at the top, an edge, and a band of light that follows the pointer. */
.pocket.is-blank, .pocket.is-gap { position: relative; aspect-ratio: 5 / 7; border-radius: 5px; background: var(--bd-slot); }
.pocket.is-blank { opacity: .75; }
.pocket.is-gap { align-items: center; justify-content: center; text-align: center; gap: 4px; }
.pocket-have[aria-pressed="true"] { background: #1f9d55; border-color: #e9fff2; color: #fff; }
/* Rare and above shimmer in their rarity colour once they are in the binder. */
.pocket.is-foil .pocket-open { box-shadow: 0 0 0 1px color-mix(in srgb, var(--rar) 60%, transparent), 0 0 14px -4px var(--rar), 0 1px 2px rgba(0, 0, 0, .35); }
.pocket.is-foil .pocket-open::after { content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none; mix-blend-mode: color-dodge; opacity: .5;
  background: linear-gradient(115deg, transparent 38%, color-mix(in srgb, var(--rar) 55%, #fff) 50%, transparent 62%); background-size: 260% 100%;
  animation: bd-foil 3.6s ease-in-out infinite; }
.pocket.is-foil .pocket-open:hover::after { opacity: .85; animation-duration: 1.6s; }
@keyframes bd-foil { from { background-position: 110% 0; } to { background-position: -10% 0; } }
/* Ticking a card slides it down into its sleeve; clearing it lets it fade back to a wish. */
.pocket.is-slide .pocket-open img { animation: bd-in .6s cubic-bezier(.2, .8, .2, 1) var(--d, 0ms) both; }
.pocket.is-slide .pocket-have { animation: bd-pop .45s ease-out calc(var(--d, 0ms) + .35s) both; }
.pocket.is-out .pocket-open img { animation: bd-out .45s ease-out var(--d, 0ms) both; }
@keyframes bd-in { from { transform: translateY(-112%) rotate(-5deg); filter: grayscale(.85) brightness(.8); opacity: .5; }
  62% { transform: translateY(3%) rotate(.6deg); filter: none; opacity: 1; } to { transform: none; } }
@keyframes bd-out { from { transform: none; filter: none; opacity: 1; } 35% { transform: translateY(-7%); }
  to { transform: none; filter: grayscale(.85) brightness(.8); opacity: .5; } }
@keyframes bd-pop { 0% { transform: scale(.6); } 60% { transform: scale(1.25); } to { transform: none; } }
/* A curled corner on the outside of a page turns it. */
/* A turning leaf and the opening cover: two faces back to back, drawn over the book. */
@media (prefers-reduced-motion: reduce) {
   .pocket.is-foil .pocket-open::after { animation: none !important; }
}

/* ---------- Versions of a card (T10) ---------- */

/* ---------- Simple or all tools (N2) ---------- */
.rail-tools[aria-pressed="true"] { color: var(--ui-accent-text); }
.rail-tools[aria-pressed="true"] svg { color: var(--ui-accent); }

/* ---------- The quick bar (N3) ---------- */
.qb-btn[aria-pressed="true"] { background: var(--ui-accent-soft); color: var(--ui-accent-text); }
@keyframes cf-insp-flash { 0%, 100% { box-shadow: none; } 30% { box-shadow: inset 0 0 0 2px var(--ui-accent); } }

/* ---------- The save indicator (N10) ---------- */
/* New and Save beside the card's name (K3). Save is the save indicator too:
   its words say whether the library has this card, its dot how the copy
   kept in this browser is doing. */
.save-state[data-state="local"] .ss-dot { display: none; }
.save-state[data-state="saving"] .ss-dot { background: var(--ui-faint); animation: cf-ss-pulse 1s ease-in-out infinite; }
.save-state[data-state="older"] .ss-dot { background: var(--ui-warn-text); }
.save-state[data-state="off"] .ss-dot { background: var(--ui-danger-text); }
.save-state[data-state="batch"] .ss-dot { background: var(--ui-accent); }
@keyframes cf-ss-pulse { 50% { opacity: .3; } }

/* Settings under a gear beside the account (K4); on a phone, in the card menu. */
.menu-head { margin: 4px 10px 6px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ui-faint); }
.menu-phone { display: none; }
@media (max-width: 760px) {
  .menu-phone { display: block; }
}

/* =====================================================================
   THE EDITOR LAYOUT (R1 to R10, N1, N7, U4)
   See script.js 13c-ii. Chrome colours are roles, as everywhere.
   ===================================================================== */

/* Front or back of the card: the panels show only what that face has. */

/* ---------- The panel's head: title, a line under it, search (N7) ---------- */
.group.is-filtered { display: none !important; }

/* ---------- Sections: an icon, a title and what is inside (R9) ---------- */
.group { padding: 4px 16px 14px; }
.group.is-folded .group-toggle svg.gt-chev { transform: rotate(-90deg); }
.group.is-folded { padding-bottom: 4px; }
.group.is-folded > .group-title { margin-bottom: 0; }

/* Something Find or a tile just went to. */
.is-found { animation: cf-found 1.6s ease-out; border-radius: 8px; }
@keyframes cf-found { 0%, 45% { background-color: var(--ui-accent-soft-2); box-shadow: 0 0 0 4px var(--ui-accent-soft-2); } 100% { background-color: transparent; box-shadow: 0 0 0 4px transparent; } }

/* The (i) beside a label: the longer explanation, on hover or focus. */
.tip {
  position: relative; display: inline-grid; place-items: center; vertical-align: 1px;
  width: 15px; height: 15px; margin-left: 4px; padding: 0; border: 1px solid var(--ui-line-2); border-radius: 50%;
  background: none; color: var(--ui-faint); font: italic 700 9.5px/1 Georgia, serif; cursor: help;
}
.tip:hover, .tip:focus-visible { color: var(--ui-accent); border-color: var(--ui-accent); outline: none; }
.tip:hover::after, .tip:focus-visible::after {
  content: attr(data-tip); position: absolute; z-index: 80; left: 50%; top: calc(100% + 7px); transform: translateX(-50%);
  width: 230px; padding: 8px 10px; border-radius: 8px; background: var(--ui-strong); color: var(--ui-bg);
  font: 400 12px/1.4 var(--font); text-align: left; text-transform: none; letter-spacing: 0; white-space: normal;
  box-shadow: 0 10px 30px -8px var(--ui-shadow-strong); pointer-events: none;
}

/* ---------- The rail (R1) ---------- */

/* ---------- Template gallery filters (R7) ---------- */
.tpl-cats .chip-btn[aria-pressed="true"], .tpl-tiers .seg-btn[aria-pressed="true"] { background: var(--ui-accent-soft); border-color: var(--ui-accent); color: var(--ui-accent-text); box-shadow: none; }

/* ---------- The Add tab's tiles (R6) ---------- */

/* ---------- The properties panel (R4) ---------- */
/* Only what is selected: with nothing picked it says how to pick something. */
/* Where there is room, it floats over the right of the stage and only
   while something is selected, so the card never moves under the pointer. */
@media (min-width: 1024px) {
  body.has-selection .workspace.props-float .panel-props { transform: none; visibility: visible; transition: transform .18s ease; }
}

/* ---------- Top bar: find a tool (N1) ---------- */
.find-item[aria-selected="true"] { background: var(--ui-accent-soft); }

/* ---------- Export: quick downloads, then one dialog (R8) ---------- */
.modal-export { width: min(820px, calc(100vw - 32px)); height: min(620px, calc(100vh - 48px)); max-height: none; overflow: hidden; }
/* Only a close button: it stays beside the title on a phone too. */
.modal-export .modal-head { flex-wrap: nowrap; }
.modal-export .modal-actions { width: auto; margin-left: auto; }
.export-tabs button[aria-selected="true"] { color: var(--ui-strong); background: var(--ui-panel); box-shadow: inset 0 0 0 1px var(--ui-line-2); }
/* A choice in a tab: a title and one line saying what it makes. */

/* ---------- The start screen (U4) ---------- */

/* ---------- Tablet and phone ---------- */
@media (max-width: 760px) {
  .modal-export { height: calc(100dvh - 24px); }
}

/* =====================================================================
   THE 3D VIEW (X5)  — script.js 13ad. Not a .modal, so it is never drawn
   at the compact zoom: the drag works in screen pixels.
   ===================================================================== */
.viewer-tools .btn[aria-pressed="true"] { background: var(--ui-accent-soft); border-color: var(--ui-accent); color: var(--ui-accent-text); }
.viewer-bg button[aria-pressed="true"] { box-shadow: inset 0 0 0 2px var(--ui-accent); }

/* =====================================================================
   MAINTENANCE BAR  — auth.js, for an administrator while the site is
   closed (api/maintenance.php). Small, at the foot, out of the way.
   ===================================================================== */
.maint-bar {
  position: fixed; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 95;
  display: flex; align-items: center; gap: 12px; max-width: calc(100vw - 32px); padding: 8px 10px 8px 14px;
  border: 1px solid var(--ui-warn-line); border-radius: 999px; color: var(--ui-warn-text);
  background: linear-gradient(var(--ui-warn-bg), var(--ui-warn-bg)), var(--ui-bg-2);
  font-size: 13px; line-height: 1.35; box-shadow: 0 10px 30px var(--ui-shadow);
}
.maint-bar a {
  flex: none; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--ui-warn-line);
  color: inherit; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.maint-bar a:hover { background: var(--ui-hover-line); }
@media (max-width: 760px) {
  .maint-bar { bottom: calc(66px + env(safe-area-inset-bottom, 0px)); border-radius: 14px; font-size: 12px; }
}


/* ---------- Style presets, live corners, isolation, info (A28, A33, A40, A42) ---------- */
.preset-tile[aria-pressed="true"] { border-color: var(--ui-accent); background: var(--ui-accent-soft); color: var(--ui-accent-text); }

/* Right-click menu on the card (V1). */
/* Typing on the card (V2): a box over the text, never part of the card. */
/* Print check (V7). */
.modal-check { width: min(560px, calc(100vw - 32px)); }
/* Send feedback (card menu). */
/* Over the export dialog, which opens it. */

/* ---------- The card menu (2026-10-18) ----------
   A labelled button in the top bar, and a floating panel of three groups:
   This card, Share and sell, Go to. A group with nothing showing goes. On a
   phone it is one column across the screen (the .menu-pop rule there). */
@keyframes cm-in { from { opacity: 0; transform: translateY(-4px) scale(.98); } }
/* The marketplace in the switch: a link to its own page, in a new tab. */
@media (max-width: 1100px) and (min-width: 761px) {
  /* Groups wrap here, so each is its own tile rather than a column with a rule beside it. */
}

/* ---------- Save, Publish and Sell under the card (2026-10-18) ----------
   One row where the caption was, so the card keeps its size: the template
   name as a small chip (its title holds the old hint), then the buttons.
   Phones keep these in the card menu: the row is hidden there. */

/* ---------- The AI at work, over the card (2026-10-18) ----------
   Beside the card's SVG inside .card-stage, never in it, so no export sees it. */
@keyframes ai-sweep { from { transform: translateX(-45%); } to { transform: translateX(45%); } }
@keyframes ai-breathe { 50% { opacity: .45; } }
@keyframes ai-spark { 0%, 100% { opacity: 0; transform: scale(.4) rotate(0); } 45% { opacity: 1; transform: scale(1) rotate(45deg); } }
@keyframes ai-spin { to { transform: rotate(360deg); } }
@keyframes ai-step { from { opacity: 0; transform: translateY(6px); } }
@keyframes ai-dot { 50% { opacity: 1; transform: translateY(-2px); } }

/* A stat's name, renamed in place (2026-10-18). Reads as the label until clicked. */
