/* Spell Sigils: the app's own layout, after base.css, which has the fonts, the colours and the base type */
html,body{height:100%;}
body{background:radial-gradient(ellipse at 50% 30%, var(--bg-1), var(--bg-0) 70%); overflow:hidden;}
/* the footer is its own grid item under the sidebar, not part of it, so that on a phone it can stay on the
   page while the sidebar becomes a drawer */
/* heights use svh, the viewport with the browser's own toolbars showing: Safari's vh is the height with
   them hidden, which pushed the bottom of this non-scrolling page off an iPad's screen. Each vh line is
   the fallback for browsers without svh */
.app{display:grid; grid-template-columns:320px 1fr; grid-template-rows:minmax(0,1fr) auto; height:100vh; height:100svh;}

/* ---------- sidebar ----------
   follows the system's light or dark setting through the colour variables (css/base.css), as the footer
   does; the stage doesn't */
.sidebar{
  grid-column:1; grid-row:1;
  background:var(--panel); color:var(--ink);
  border-right:1px solid var(--line);
  display:flex; flex-direction:column; min-height:0;
}
.sidebar h1{
  font-family:'Cinzel', serif; font-size:1.05rem; font-weight:700; letter-spacing:.08em;
  color:var(--ink); margin:0; padding:18px 16px 10px; text-transform:uppercase;
}
.sidebar h1 span{display:block; font-family:'EB Garamond',serif; font-weight:400; font-style:italic;
  font-size:.72rem; letter-spacing:.03em; color:var(--ink-dim); text-transform:none; margin-top:2px;}
.search{padding:0 14px 10px;}
.search input{
  width:100%; background:var(--field); border:1px solid var(--line); border-radius:6px;
  color:var(--ink); padding:8px 10px; font-family:inherit; font-size:.95rem;
}
.search input:focus{outline:none; border-color:var(--field-focus);}
.filters{padding:0 14px 10px; display:flex; flex-wrap:wrap; gap:6px;}
.filters[hidden]{display:none;} /* .filters' own display:flex is equal-specificity to the UA [hidden] rule and would otherwise win */
/* the chips are buttons: their own font, line height and margin are reset so they look as plain boxes did */
.chip, .rank-chip{appearance:none; -webkit-appearance:none; margin:0; line-height:normal;}
.chip{
  font-family:'Cinzel',serif; font-size:.62rem; letter-spacing:.05em; text-transform:uppercase;
  padding:5px 9px; border-radius:20px; border:1px solid var(--line); cursor:pointer;
  color:var(--ink-dim); background:var(--field); user-select:none; transition:.15s;
}
.chip[aria-pressed="true"]{color:#0a0b10; font-weight:700;}
.chip[data-trad="arcane"][aria-pressed="true"]{background:hsl(var(--arcane)); box-shadow:0 0 10px hsla(var(--arcane)/.6);}
.chip[data-trad="divine"][aria-pressed="true"]{background:hsl(var(--divine)); box-shadow:0 0 10px hsla(var(--divine)/.6);}
.chip[data-trad="occult"][aria-pressed="true"]{background:hsl(var(--occult)); box-shadow:0 0 10px hsla(var(--occult)/.6);}
.chip[data-trad="primal"][aria-pressed="true"]{background:hsl(var(--primal)); box-shadow:0 0 10px hsla(var(--primal)/.6);}
.chip[data-trad="ritual"][aria-pressed="true"]{background:hsl(var(--ritual)); box-shadow:0 0 10px hsla(var(--ritual)/.6);}
.chip[data-trad="focus"][aria-pressed="true"]{background:hsl(var(--focus)); box-shadow:0 0 10px hsla(var(--focus)/.6);}
/* class subselector chips share Focus's own color — they're a refinement of that same selection, not a new axis */
/* each class chip carries its own --class-hue custom property (set inline in JS from hueForClass, a
   bare number) — 'other' (no single owning class) has none set, so it falls back to 190, --focus's own
   hue (can't fall back to var(--focus) itself here: that holds a full "H S% L%" triplet, not a bare
   hue, and splicing it into `hsl(var(--focus) 62% 56%)` would produce five components, not three) */
.chip[data-class][aria-pressed="true"]{background:hsl(var(--class-hue, 190) 62% 56%); box-shadow:0 0 10px hsl(var(--class-hue, 190) 62% 56% / .6);}
.rank-row{padding:0 14px 12px; display:flex; flex-wrap:wrap; gap:4px;}
.rank-chip{
  width:24px; height:24px; display:flex; align-items:center; justify-content:center; padding:0;
  border-radius:50%; border:1px solid var(--line); background:var(--field);
  font-family:inherit; font-size:.68rem; color:var(--ink-dim); cursor:pointer;
}
.rank-chip[aria-pressed="true"]{background:var(--pressed); color:var(--pressed-ink); border-color:var(--pressed-line);}
.count{padding:0 16px 8px; font-size:.7rem; color:var(--ink-faint); letter-spacing:.03em;}
.list{list-style:none; margin:0; padding:0 0 16px; overflow-y:auto; flex:1; border-top:1px solid var(--line);}
.list li{
  padding:8px 16px; font-size:.88rem; cursor:pointer; color:var(--ink-dim);
  border-left:3px solid transparent; display:flex; justify-content:space-between; gap:8px;
}
.list li:hover{background:var(--hover); color:var(--ink);}
/* the footer's links to help (with the Paizo notice and credits) and the atlas */
.legal{
  grid-column:1; grid-row:2; padding:10px 16px 14px; font-size:.62rem; line-height:1.4; color:var(--ink-faint);
  border-top:1px solid var(--line); border-right:1px solid var(--line); background:var(--footer);
}
.legal p{margin:0 0 6px;}
.legal p:last-child{margin-bottom:0;}
.legal a{color:var(--ink-dim);}
.list li.active{background:var(--selected); color:var(--ink-strong); border-left-color:var(--dot,#888);}
.list li .r{font-size:.7rem; color:var(--ink-faint); font-variant:small-caps;}
.list::-webkit-scrollbar{width:8px;}
.list::-webkit-scrollbar-thumb{background:var(--scroll); border-radius:4px;}

/* keyboard focus: a ring on every control, shown only when focus came from the keyboard. List items sit in
   a scrolling box that would clip a ring outside them, so theirs is drawn inside */
.chip:focus-visible, .rank-chip:focus-visible, .tool:focus-visible, .topbar-btn:focus-visible, .drawer-close:focus-visible,
.export-panel button:focus-visible, .export-panel select:focus-visible, .export-panel input:focus-visible{
  outline:2px solid var(--focus-ring); outline-offset:2px;
}
.list:focus-visible{outline:none;}
.list li:focus-visible{outline:2px solid var(--focus-ring); outline-offset:-2px;}

/* ---------- stage ---------- */
/* a size container, so the readout's placement can follow the stage's own shape (see below) */
.stage{
  grid-column:2; grid-row:1 / 3; position:relative; display:flex; flex-direction:column; align-items:center;
  justify-content:center; min-height:0; padding:20px; container:stage / size;
}
/* the phone layout's top bar, drawer close button and backdrop */
.topbar, .drawer-close, .drawer-backdrop{display:none;}
/* in a portrait stage: short enough to leave the readout its height below, and never wider than the
   stage beside the 320px sidebar */
.circle-wrap{width:min(72vh, 62vw, 100vw - 360px); width:min(72svh, 62vw, 100vw - 360px); aspect-ratio:1; position:relative;}
#sigil{width:100%; height:100%; overflow:visible;}
/* the resting tint: two sharp copies of the drawing in the spell's main color laid underneath, which
   lighten semi-transparent lines and anti-aliased edges toward it. Chrome draws them; Safari skips a 0px
   drop-shadow and shows crisp lines, which keeps it smooth (see setGlow in js/sigil.js). While the glow
   shows, the SVG filter on the sigil carries its own halos instead */
#sigil{filter:drop-shadow(0 0 0 var(--glowcolor, transparent)) drop-shadow(0 0 0 var(--glowcolor, transparent));}
#sigil.lit{filter:none;}
/* held still by setIdleStill: the idle comets hide; a draw-on spark still rides a new spell's lines */
#sigil.still .comet[data-idle]{visibility:hidden;}

/* in a portrait stage the readout sits centred under the circle */
.readout{text-align:center; max-width:640px; margin-top:6px;}
/* says why a link's spell wasn't drawn (see showFromHash in js/ui.js) */
.readout .note{font-style:italic; font-size:.85rem; color:var(--ink-dim); margin-bottom:8px;}
.readout .name{
  font-family:'Cinzel',serif; font-weight:700; font-size:1.4rem; letter-spacing:.04em;
  color:#fff; text-shadow:0 0 18px var(--nameglow, rgba(150,170,255,.55));
}
.readout .rank{
  font-style:italic; color:var(--ink-dim); font-size:.9rem; margin-top:2px;
}
.badges{display:flex; justify-content:center; gap:6px; margin:10px 0 8px; flex-wrap:wrap;}
.badge{
  font-family:'Cinzel',serif; font-size:.62rem; letter-spacing:.06em; text-transform:uppercase;
  padding:4px 10px; border-radius:20px; color:#0a0b10; font-weight:700;
}
.traits{display:flex; justify-content:center; gap:5px; flex-wrap:wrap;}
.trait-tag{
  font-size:.68rem; color:var(--ink-dim); border:1px solid var(--line);
  padding:2px 8px; border-radius:12px; background:rgba(255,255,255,.02);
}
.trait-tag.curated{color:#e9ebf7; border-color:#454a72; background:rgba(120,130,200,.12);}

/* in a landscape stage the circle fills the stage's height and the readout splits into the corners the
   circle leaves empty: the toolbar keeps the top-left, the name and rank take the top-right, the
   tradition badges the bottom-left and the traits the bottom-right. The name is a little smaller here,
   and the 40-odd names over 24 characters smaller again, so that in a nearly square stage a long name
   wrapping onto a second line stays clear of the drawing */
@container stage (orientation: landscape){
  .circle-wrap{width:min(100cqw, 100cqh);}
  .readout{display:contents;}
  .readout .title, .badges, .traits{position:absolute; max-width:230px;}
  .readout .title{top:14px; right:20px; text-align:right;}
  .readout .name{font-size:1.2rem;}
  .readout .name.long{font-size:1rem;}
  .badges{bottom:16px; left:20px; margin:0; justify-content:flex-start;}
  .traits{bottom:16px; right:20px; justify-content:flex-end;}
}

/* ---------- stage toolbar ----------
   a row of icon buttons pinned to .stage's own top-left, where the centred circle leaves room: the two
   display modes first, lit while on, then a gap and the two one-off actions. Each button's name is its
   aria-label and tooltip */
.toolbar{position:absolute; top:14px; left:18px; display:flex; align-items:center; gap:6px;}
.tool-gap{width:8px;}
/* solid fill and a hint of depth, so they read as buttons rather than bordered pills; the phone top
   bar's Spells button shares the look */
.tool, .topbar-btn{
  border-radius:6px; border:1px solid var(--line); cursor:pointer;
  color:var(--ink-dim); background:#1b1e30; user-select:none; transition:.15s;
  box-shadow:0 1px 0 rgba(255,255,255,.04) inset, 0 1px 3px rgba(0,0,0,.4);
  appearance:none; -webkit-appearance:none;
}
.tool:hover, .topbar-btn:hover{background:#242840; color:var(--ink);}
.tool{display:flex; align-items:center; justify-content:center; width:34px; height:34px; padding:0;}
/* drawn in the trait glyphs' line style */
.tool svg{width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round;}
.tool[aria-pressed="true"], .tool[aria-expanded="true"]{background:#e8c878; color:#2a2410; border-color:#c9a24a; box-shadow:0 0 10px rgba(232,200,120,.6);}
/* disabled: max glow while parchment is on */
.tool:disabled{opacity:.35; pointer-events:none;}

/* the Export panel, opening below the toolbar (js/export.js); dark in both modes, as a floating control */
.export-panel{
  position:absolute; top:calc(100% + 8px); left:0; z-index:20; width:250px; padding:12px 14px 10px;
  border-radius:10px; border:1px solid var(--line); background:#11131f; color:var(--ink);
  box-shadow:0 8px 24px rgba(0,0,0,.5);
}
.export-panel[hidden]{display:none;}
.export-what{display:grid; gap:7px; margin-bottom:12px; font-size:.95rem;}
.export-what label{display:flex; align-items:center; gap:8px; cursor:pointer;}
.export-what input{accent-color:#e8c878; margin:0;}
.export-what .fmt{color:var(--ink-faint); font-size:.75rem; letter-spacing:.04em;}
.export-what [hidden]{display:none;}
.export-what select{
  margin-left:auto; font:inherit; font-size:.8rem; color:var(--ink); background:#0c0e17;
  border:1px solid var(--line); border-radius:5px; padding:2px 4px;
}
.export-ground{display:flex; align-items:center; gap:8px; margin:-4px 0 12px; font-size:.9rem; color:var(--ink-dim); cursor:pointer;}
.export-ground input{accent-color:#e8c878; margin:0;}
.export-ground:has(input:disabled){opacity:.4; cursor:default;}
.export-actions, .export-progress{display:flex; gap:6px;}
.export-progress{align-items:center; flex-wrap:wrap; margin-top:10px;}
.export-progress[hidden]{display:none;}
/* the animation's frames as they're made; the live sigil is hidden meanwhile */
.export-progress canvas{width:100%; aspect-ratio:1; border-radius:6px; margin-bottom:2px;}
.stage.exporting .circle-wrap{visibility:hidden;}
.export-progress progress{flex:1; height:8px; accent-color:#e8c878;}
.export-actions button, .export-progress button{
  flex:1; padding:7px 6px; border-radius:6px; border:1px solid var(--line); cursor:pointer;
  font-family:'Cinzel',serif; font-size:.66rem; letter-spacing:.05em; text-transform:uppercase;
  color:var(--ink-dim); background:#1b1e30; appearance:none; -webkit-appearance:none;
}
.export-progress button{flex:none;}
.export-actions button[hidden]{display:none;}
.export-actions button:hover:not(:disabled), .export-progress button:hover{background:#242840; color:var(--ink);}
.export-actions button:disabled{opacity:.35; cursor:default;}
/* an animation made for sharing, waiting for the second tap */
.export-actions button.ready{color:#2a2410; background:#e8c878; border-color:#c9a24a;}
.export-status{margin:8px 0 0; min-height:1.2em; font-size:.82rem; font-style:italic; color:var(--ink-dim);}
/* font set directly, not inherited, so a native <button>'s own UI font can't win */
.topbar-btn{padding:7px 10px; font-family:'Cinzel',serif; font-size:.68rem; letter-spacing:.05em; text-transform:uppercase;}

/* ---------- parchment ----------
   the whole stage becomes paper: a faint tileable fractal-noise grain, tinted brown (feColorMatrix's alpha
   row, the last '0.05', keeps it faint), two soft stains, and a light ivory ground darkening a little
   toward the edges. The sigil's ink rules are in js/ui.js (inkRules), shared with copied images, which
   also sets the colours used here as --parchment-ink and --paper-0 to 2 */
.stage.parchment{
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0.32  0 0 0 0 0.24  0 0 0 0 0.13  0 0 0 0.05 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"),
    radial-gradient(ellipse at 30% 25%, rgba(150,110,60,.05), transparent 55%),
    radial-gradient(ellipse at 75% 80%, rgba(120,85,40,.06), transparent 60%),
    radial-gradient(ellipse at 50% 50%, var(--paper-0), var(--paper-1) 70%, var(--paper-2) 100%);
}
/* an inked sigil doesn't glow: no glow filter, and no resting tint */
.stage.parchment #sigil, .stage.parchment #sigil .glow{filter:none;}
/* the readout, toolbar and phone top bar in ink; the tradition badges keep their colours */
.stage.parchment .readout .name{color:var(--parchment-ink); text-shadow:none;}
.stage.parchment .readout .rank, .stage.parchment .readout .note{color:#6b5d4d;}
.stage.parchment .trait-tag{color:#5a4d40; border-color:#cbbfa3; background:rgba(255,255,255,.25);}
.stage.parchment .trait-tag.curated{color:var(--parchment-ink); border-color:#a99777; background:rgba(150,120,70,.08);}
.stage.parchment .tool, .stage.parchment .topbar-btn{color:#5a4d40; background:#f2ece0; border-color:#cbbfa3; box-shadow:none;}
.stage.parchment .tool:hover, .stage.parchment .topbar-btn:hover{color:var(--parchment-ink); background:#e9e1cf;}
.stage.parchment .tool[aria-pressed="true"], .stage.parchment .tool[aria-expanded="true"]{color:#2a2410; background:#e8c878; border-color:#c9a24a;}
.stage.parchment .topbar{background:rgba(244,239,227,.92); border-color:#cbbfa3;}
.stage.parchment .topbar-title{color:var(--parchment-ink);}

/* ---------- phones: the sidebar becomes a drawer ----------
   below 700px wide there's no room for the sidebar beside the circle, and below 560px tall, a phone on
   its side, the sidebar can't fit its filters and its list. The page scrolls instead: a top bar with a
   Spells button, the sigil at full width, the readout, the toolbar and then the footer, which stays on
   the page rather than in the drawer. The sidebar slides over it from the left
   while body.drawer-open is set (js/ui.js), which also stops the page behind it scrolling. */
@media (max-width:699px), (max-height:559px){
  body{overflow:auto;}
  body.drawer-open{overflow:hidden;}
  .app{display:block; height:auto;}
  /* clip, not hidden: spilling medallions mustn't widen the page, and clip
     keeps the top bar's position:sticky working. Not a size container here: the page's height comes from
     its content, so the readout always sits under the circle */
  .stage{padding:0 16px 20px; overflow-x:clip; container-type:normal;}
  .topbar{
    display:flex; align-items:center; justify-content:space-between; align-self:stretch;
    position:sticky; top:0; z-index:10; margin:0 -16px 12px; padding:10px 16px;
    background:rgba(5,6,10,.88); border-bottom:1px solid var(--line);
  }
  .topbar-title{font-family:'Cinzel',serif; font-size:.95rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase;}
  /* the full width less a margin for medallions that spill past the circle, and short enough on a phone
     on its side to fit under the top bar */
  .circle-wrap{width:min(100vw - 40px, 100vh - 80px); width:min(100vw - 40px, 100svh - 80px);}
  .readout{order:1; max-width:none; margin-top:8px;}
  .toolbar{position:relative; order:2; justify-content:center; margin-top:16px;}
  .export-panel{left:50%; transform:translateX(-50%);}
  .legal{border-right:none;}

  .sidebar{
    position:fixed; top:0; bottom:0; left:0; z-index:30; width:min(340px, 88vw);
    background:var(--bg-1); border-right:1px solid var(--line);
    transform:translateX(-100%); visibility:hidden; transition:transform .2s ease, visibility 0s linear .2s;
  }
  body.drawer-open .sidebar{transform:none; visibility:visible; transition:transform .2s ease;}
  .drawer-close{
    display:block; position:absolute; top:12px; right:10px; width:36px; height:36px; padding:0;
    border:1px solid var(--line); border-radius:6px; background:var(--raised); color:var(--ink-dim);
    font-size:1.3rem; line-height:1; cursor:pointer;
  }
  body.drawer-open .drawer-backdrop{display:block; position:fixed; inset:0; z-index:25; background:rgba(0,0,0,.55);}
}
@media (prefers-reduced-motion:reduce){
  .sidebar{transition:none !important;}
}
