/* fonts are self-hosted: no requests to Google, works with a strict CSP */
@font-face { font-family: 'IBM Plex Mono'; font-weight: 400; font-display: swap; src: url(fonts/ibm-plex-mono-latin-400-normal.woff2) format('woff2'); }
@font-face { font-family: 'IBM Plex Mono'; font-weight: 500; font-display: swap; src: url(fonts/ibm-plex-mono-latin-500-normal.woff2) format('woff2'); }
@font-face { font-family: 'IBM Plex Sans'; font-weight: 300; font-display: swap; src: url(fonts/ibm-plex-sans-latin-300-normal.woff2) format('woff2'); }
@font-face { font-family: 'IBM Plex Sans'; font-weight: 400; font-display: swap; src: url(fonts/ibm-plex-sans-latin-400-normal.woff2) format('woff2'); }

:root {
  --bg: #f5f5f5; --surface: #ffffff; --surface-2: #efefef;
  --line: #d4d4d4; --line-soft: #e6e6e6;
  --text: #151515; --muted: #5c5c5c; --faint: #8a8a8a;
  --accent: #c2334f; --accent-hover: #a92a44; --accent-dim: #e9b8c3;
  --checker-a: #ffffff; --checker-b: #ececec;
  --dim: #b3b3b3;
  --mono: 'IBM Plex Mono', ui-monospace, Consolas, monospace;
  --sans: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  box-sizing: border-box;
  padding-top: env(safe-area-inset-top, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0d0d0d; --surface: #111; --surface-2: #151515;
    --line: #2a2a2a; --line-soft: #1e1e1e;
    --text: #f0ede6; --muted: #8f8c86; --faint: #6e6e6a;
    --accent: #D94162; --accent-hover: #e8556f; --accent-dim: #4a1f2a;
    --checker-a: #101010; --checker-b: #1d1d1d;
    --dim: #4a4a47;
  }
}
:root[data-theme="dark"] {
  --bg: #0d0d0d; --surface: #111; --surface-2: #151515;
  --line: #2a2a2a; --line-soft: #1e1e1e;
  --text: #f0ede6; --muted: #8f8c86; --faint: #6e6e6a;
  --accent: #D94162; --accent-hover: #e8556f; --accent-dim: #4a1f2a;
    --checker-a: #101010; --checker-b: #1d1d1d;
    --dim: #4a4a47;
}
html { scroll-padding-top: env(safe-area-inset-top, 0px); background: var(--bg); }
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body { background: var(--bg); color: var(--text); font-family: var(--mono); }
body.lock { overflow: hidden; }
button, input, select { font: inherit; color: inherit; }
img { max-width: 100%; }

.app { height: 100%; container-type: size; }
/* one square size drives the whole page: header, toolbar and grid all share the grid's width,
   so the page stays centered instead of leaving a gap on the right */
.wrap { --gap: 4px; --pad: 20px; --chrome: 210px;
        --s: max(90px, min((100cqw - 2 * var(--pad) - 7 * var(--gap)) / 8, (100cqh - var(--chrome) - 3 * var(--gap)) / 4));
        width: calc(8 * var(--s) + 7 * var(--gap)); height: 100%; margin: 0 auto; padding: var(--pad) 0; display: flex; flex-direction: column; }

header { flex: none; height: 70px; display: grid; grid-template-columns: minmax(120px, 1fr) minmax(0, 520px) minmax(0, 1fr); gap: 2rem; align-items: start; }
.brand { font-size: 20px; font-weight: 500; letter-spacing: -0.02em; padding-top: 2px; color: var(--text); text-decoration: none; justify-self: start; }
.brand:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.brand small { display: block; font-family: var(--sans); font-weight: 300; font-size: 12px; color: var(--faint); letter-spacing: 0.02em; margin-top: 4px; }
/* the two halves of one shape around the title: both views share the shape's height range, so the halves stay
   lined up as if the title were set into the cut. The viewBox crops the other half away.
   Sizes and offsets come from the approved mockup, measured against the real fonts: icons 2.7x the height of
   "cora"'s lowercase letters, the subtitle about a third of "cora", gaps measured from the visible letter edges */
.brand:has(.brand-icon) { display: inline-flex; align-items: flex-start; }
.brand-icon { flex: none; height: 45.03px; fill: currentColor; }
.brand-icon.left { width: 19.64px; }    /* 45.03 * 1500 / 3440 */
.brand-icon.right { width: 18.33px; }   /* 45.03 * 1400 / 3440 */
.brand-text { position: relative; display: block; flex: none; width: 74.24px; height: 45.03px; margin: 0 5.21px 0 2.73px; }
.brand-name { position: absolute; left: 0; top: -3.44px; font-size: 32px; line-height: 1; white-space: nowrap; }
/* left: the "b" of "beta" starts 1.75px after the "c" (ink to ink), as in the mockup */
.brand .brand-text small { position: absolute; left: 2.96px; top: 32.08px; margin: 0; font-size: 11.46px; line-height: 1; white-space: nowrap; }

/* search, styled after the theme's input row */
.search { position: relative; width: 100%; }
.input-row { display: flex; width: 100%; border: 1px solid var(--line); background: var(--surface); }
.input-row:focus-within { border-color: var(--faint); }
.field { flex: 1; display: flex; flex-wrap: wrap; align-items: center; gap: 4px; padding: 3px 10px; min-width: 0; }
.field input { flex: 1; min-width: 10ch; background: transparent; border: none; outline: none; padding: 4px 2px; font-size: 13px; caret-color: var(--accent); }
.field input::placeholder { color: var(--faint); opacity: .7; }
.go { background: var(--accent); border: none; padding: 0 16px; font-size: 12px; color: #fff; cursor: pointer; font-weight: 500; }
.go:hover { background: var(--accent-hover); }
.go:focus-visible, .chip button:focus-visible, .text-btn:focus-visible, .tag-link:focus-visible, .tag-x:focus-visible, .nav:focus-visible, .close:focus-visible, select:focus-visible, .strip button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* chips: fixed height, 8px of room left of the text and around the cross on the right */
.chip { display: inline-flex; align-items: center; height: 25px; font-size: 12px; padding: 0 0 0 8px; border: 1px solid var(--line); background: var(--surface-2); white-space: nowrap; }
.chip.neg { border-color: var(--accent); color: var(--accent); }
.chip button { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 100%; padding: 0; background: none; border: none; color: inherit; cursor: pointer; opacity: .6; }
.x-icon { display: block; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; }
.chip button:hover { opacity: 1; }

.suggest { position: absolute; left: 0; right: 0; top: 100%; margin-top: -1px; list-style: none; background: var(--surface); border: 1px solid var(--line); z-index: 5; max-height: 330px; overflow-y: auto; }
.suggest[hidden] { display: none; }
.opt { display: flex; justify-content: space-between; gap: 1rem; padding: 9px 14px; font-size: 13px; color: var(--muted); cursor: pointer; }
.opt.active { background: var(--surface-2); color: var(--text); box-shadow: inset 2px 0 0 var(--accent); }
.opt mark { background: none; color: var(--accent); }
.opt .neg { color: var(--accent); margin-right: 2px; }
.opt-count { color: var(--faint); font-size: 12px; }
.opt-new { color: var(--faint); font-size: 12px; }

.hint { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: .5rem; font-family: var(--sans); font-weight: 300; font-size: 12px; line-height: 1.7; color: var(--faint); letter-spacing: 0.01em; }
header .hint { text-align: center; }  /* the shortcut line, centered under the search bar */
.hint kbd { font-family: var(--mono); font-size: 11px; border: 1px solid var(--line); padding: 0 4px; color: var(--muted); }

.toolbar { display: flex; flex-wrap: nowrap; justify-content: space-between; align-items: center; gap: 1rem; flex: none; height: 36px; margin: 12px 0; border-left: 2px solid var(--line-soft); padding: 0 0 0 1rem; font-size: 12px; color: var(--muted); }
.toolbar label { display: flex; align-items: center; gap: 10px; font-family: var(--sans); color: var(--faint); }
select { background: var(--surface); border: 1px solid var(--line); padding: 6px 10px; font-family: var(--mono); font-size: 12px; cursor: pointer; }
.dot { display: inline-block; width: 5px; height: 5px; background: var(--accent); border-radius: 50%; margin-right: 8px; vertical-align: 2px; }

.controls { display: flex; gap: 18px; }
/* hidden: thumbnail goes half transparent over a checkerboard, like persephone.
   background-attachment: fixed keeps the squares aligned across all tiles */
.tile.hidden { background-color: var(--checker-a); background-image: conic-gradient(var(--checker-b) 25%, transparent 0 50%, var(--checker-b) 0 75%, transparent 0); background-size: 24px 24px; background-attachment: fixed; }
.tile.hidden img { opacity: .5; }
.meta select { padding: 2px 6px; font-size: 12px; }
.admin-only { display: contents; }
.admin-only[hidden] { display: none; }
.toast { position: fixed; top: calc(16px + env(safe-area-inset-top, 0px)); right: calc(16px + env(safe-area-inset-right, 0px)); z-index: 50; max-width: min(360px, calc(100vw - 32px)); background: var(--surface); border: 1px solid var(--line); border-left: 2px solid var(--accent); padding: 10px 16px; font-size: 12px; pointer-events: none; }  /* top right, never blocks clicks */
.toast[hidden] { display: none; }
/* always 4 rows tall, also on a last page with only a few media, so the pager below never moves */
.grid { display: grid; grid-template-columns: repeat(8, var(--s)); grid-template-rows: repeat(4, var(--s)); grid-auto-rows: var(--s); gap: var(--gap); }
.pager { flex: none; height: 28px; margin-top: 12px; display: flex; justify-content: center; align-items: center; gap: 12px; font-size: 12px; color: var(--muted); }
.nums { display: flex; align-items: center; gap: 4px; }
.nums .gap { width: 36px; height: 28px; display: inline-flex; align-items: center; justify-content: center; color: var(--faint); }
.nums .gap svg { display: block; fill: currentColor; }
.pager button[aria-current="page"] { background: var(--accent); border-color: var(--accent); color: #fff; cursor: default; }
/* every slot has the same fixed width, so nothing shifts when the page changes */
.pager button { width: 36px; padding: 0; height: 28px; font-size: 12px; font-variant-numeric: tabular-nums; background: var(--surface); border: 1px solid var(--line); cursor: pointer; }
#pPrev, #pNext { font-size: 15px; }
.pager button:hover:not(:disabled):not([aria-current]) { background: var(--surface-2); border-color: var(--faint); color: var(--text); }
.pager button:disabled { opacity: .3; cursor: default; }
.pager button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tile { position: relative; display: block; width: 100%; aspect-ratio: 1 / 1; padding: 0; border: none; background: var(--surface); cursor: zoom-in; overflow: hidden; }
.tile img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* while the thumbnail loads, the tile shows the media's own color (set inline), then the image fades in */
.tile img { transition: opacity .2s ease-out; }
.tile img.loading { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .tile img { transition: none; } }
.tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.tile .cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 22px 10px 8px; font-size: 11px; text-align: left; color: #f0ede6; background: linear-gradient(transparent, rgba(0,0,0,.72)); opacity: 0; }
.tile:hover .cap, .tile:focus-visible .cap { opacity: 1; }
.badges { position: absolute; top: 8px; left: 8px; display: flex; gap: 4px; }
/* fixed height, text centered vertically and horizontally next to the colored bar */
.badge { display: inline-flex; align-items: center; height: 18px; font-size: 11px; line-height: 1; padding: 0 8px; background: rgba(13,13,13,.82); color: #f0ede6; border-left: 3px solid #D94162; }
.badge.hidden-tag { border-left-color: #8f8c86; }
/* videos: filled play triangle in the middle with a dark edge, length in the bottom left corner */
.tile .play { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; pointer-events: none; }
.tile .play svg { width: 30%; min-width: 28px; max-width: 56px; height: auto; filter: drop-shadow(0 1px 6px rgba(0, 0, 0, .45)); }
.tile .play path { fill: #f0ede6; stroke: #f0ede6; stroke-width: 2.5; stroke-linejoin: miter; stroke-miterlimit: 10; }
.tile .play path.under { fill: none; stroke: rgba(13, 13, 13, .55); stroke-width: 5.5; }
/* bottom left corner: 18+ chip, then the video length. Both 18px tall with the text centered in the box */
.tile .corner { position: absolute; left: 6px; bottom: 6px; z-index: 1; display: flex; gap: 4px; pointer-events: none; }
.tile .dur { display: inline-flex; align-items: center; justify-content: center; height: 18px; padding: 0 6px; font-size: 11px; line-height: 1;
             font-variant-numeric: tabular-nums; color: #f0ede6; background: rgba(13, 13, 13, .72); }
.tile .nsfw-chip { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 18px; font-size: 10px; line-height: 1;
                   color: #fff; background: #c5274a; }
body.nsfw-shown .tile .nsfw-chip { display: none; }
/* nsfw thumbnails: blurred until the switch is on. The blurred image overhangs the tile by 84px (3x the blur) on every
   side, so the soft edge of the blur (darker, it mixes in the transparent outside) is clipped away at any tile size */
.tile img.nsfw { transition: filter .2s, margin .2s, width .2s, height .2s, max-width .2s, opacity .2s ease-out; }
body:not(.nsfw-shown) .tile img.nsfw { filter: blur(28px); margin: -84px; width: calc(100% + 168px); height: calc(100% + 168px); max-width: calc(100% + 168px); }
@media (prefers-reduced-motion: reduce) { .tile img.nsfw { transition: none; } }

/* nsfw switch in the toolbar */
.nsfw-switch { display: flex; align-items: center; gap: 10px; padding: 0; background: none; border: none; font-family: var(--sans); font-size: 12px; color: var(--faint); cursor: pointer; }
.nsfw-switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.nsfw-switch .track { position: relative; display: block; width: 30px; height: 16px; border: 1px solid var(--line); background: var(--surface); pointer-events: none; transition: background .15s, border-color .15s; }
.nsfw-switch .knob { position: absolute; top: 2px; left: 2px; width: 10px; height: 10px; background: var(--faint); transition: left .15s; }
.nsfw-switch[aria-checked="true"] .track { border-color: var(--accent); background: var(--accent-dim); }
.nsfw-switch[aria-checked="true"] .knob { left: 16px; background: var(--accent); }
@media (prefers-reduced-motion: reduce) { .nsfw-switch .track, .nsfw-switch .knob { transition: none; } }

/* viewer, nsfw while the switch is off: the blurred thumbnail in a box of the media's size, the notice on top.
   .sizer is an empty SVG of the media's size, so the .stage img rules size the box like the real image */
.nsfw-cover { position: relative; display: flex; max-width: 100%; max-height: 100%; overflow: hidden; cursor: default; }
.nsfw-cover[hidden] { display: none; }
.nsfw-cover .sizer { visibility: hidden; }
/* the blur overhangs by 144px (3x the blur) on every side, so its soft (darker) edge is clipped away */
.nsfw-cover .blurred { position: absolute; top: -144px; left: -144px; width: calc(100% + 288px); height: calc(100% + 288px);
                       max-width: none; max-height: none; object-fit: cover; filter: blur(48px); }
.nsfw-notice { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 24px; }
.nsfw-notice .box { max-width: 320px; padding: 18px 20px; display: flex; flex-direction: column; align-items: center; gap: 12px;
                    background: rgba(13, 13, 13, .78); border: 1px solid rgba(240, 237, 230, .2); }
.nsfw-notice .nsfw-chip { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 24px;
                          font-size: 12px; line-height: 1; color: #fff; background: #c5274a; }
.nsfw-notice p { text-align: center; font-family: var(--sans); font-weight: 300; font-size: 14px; line-height: 1.6; color: #f0ede6; }

/* set strip in the viewer: same blur and a small 18+ chip */
.strip .nsfw-chip { position: absolute; left: 3px; bottom: 3px; z-index: 1; display: inline-flex; align-items: center; justify-content: center;
                    width: 24px; height: 14px; font-size: 9px; line-height: 1; color: #fff; background: #c5274a; pointer-events: none; }
.strip button.cover .nsfw-chip { bottom: 17px; }  /* above the comic's "cover" label */
body.nsfw-shown .strip .nsfw-chip { display: none; }
body:not(.nsfw-shown) .strip img.nsfw { filter: blur(6px); margin: -18px; width: calc(100% + 36px); height: calc(100% + 36px); max-width: calc(100% + 36px); }
.empty { grid-column: 1 / -1; grid-row: 1 / -1; align-self: center; padding: 4rem 0; text-align: center; font-family: var(--sans); font-size: 13px; color: var(--faint); }

/* viewer */
.viewer { position: fixed; inset: 0; z-index: 20; background: var(--bg); display: grid; grid-template-columns: minmax(0, 1fr) 360px; padding-top: env(safe-area-inset-top, 0px); padding-bottom: env(safe-area-inset-bottom, 0px); }
.viewer[hidden] { display: none; }
.stage { cursor: zoom-out; position: relative; display: flex; align-items: center; justify-content: center; padding: 24px 68px; min-width: 0; min-height: 0; }
.stage img { cursor: default; max-height: calc(100dvh - 48px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)); object-fit: contain; }
#vImg.fade-in { animation: v-fade .2s ease-out; }
@keyframes v-fade { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { #vImg.fade-in { animation: none; } }
.stage video { cursor: default; width: auto; height: auto; max-width: 100%; max-height: calc(100dvh - 48px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)); background: #000; }
.nav { position: absolute; top: 50%; transform: translateY(-50%); width: 42px; height: 58px; background: var(--surface); border: 1px solid var(--line); font-size: 20px; cursor: pointer; }
.nav:hover { border-color: var(--accent); color: var(--accent); }
.nav:disabled { opacity: .3; cursor: default; border-color: var(--line); color: inherit; }
.prev { left: 14px; } .next { right: 14px; }

.panel { background: var(--surface); border-left: 1px solid var(--line-soft); padding: 26px 24px; overflow-y: auto; display: flex; flex-direction: column; gap: 28px; }
.panel-head { display: flex; justify-content: space-between; align-items: center; }
.panel h2 { font-size: 22px; font-weight: 500; letter-spacing: -0.02em; line-height: 1.2; }
.close { flex: none; width: 34px; height: 34px; display: flex; align-items: center; justify-content: center; padding: 0;
         background: none; border: 1px solid var(--line); color: var(--text); cursor: pointer; }
/* drawn, not a × character: the font puts that glyph off the vertical middle */
.close-x { display: block; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: square; }
.close:hover { border-color: var(--accent); color: var(--accent); }
/* rows centered: a label next to a taller date or visibility box sits at the box's middle */
.meta { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 7px 18px; font-size: 12px; }
.meta dt { font-family: var(--sans); color: var(--faint); }
.swatch { display: inline-block; width: 10px; height: 10px; vertical-align: -1px; margin-right: 6px; border: 1px solid var(--line); }
.panel h3 { font-family: var(--sans); font-weight: 400; font-size: 12px; color: var(--faint); margin-bottom: 10px; }
.row-head { display: flex; justify-content: space-between; align-items: baseline; }
.text-btn { background: none; border: none; color: var(--accent); font-family: var(--mono); font-size: 12px; cursor: pointer; }
.text-btn:hover { color: var(--accent-hover); }

.strip { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 4px; }
.strip button { flex: 0 0 54px; height: 70px; padding: 0; border: 1px solid var(--line); background: none; cursor: pointer; overflow: hidden; }
.strip button img { width: 100%; height: 100%; object-fit: cover; display: block; }
.strip button { position: relative; border: none; }
/* the frame is an overlay on the exact edge: 1px gray normally, 2px pink for the current page */
.strip button::after { content: ''; position: absolute; inset: 0; border: 1px solid var(--line); pointer-events: none; }
.strip button.current::after { border: 2px solid var(--accent); }

.tag-list { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; }
.tag-list li { display: flex; }
.tag-link, .tag-x { background: none; border: 1px solid var(--line); font-family: var(--mono); font-size: 12px; padding: 5px 10px; cursor: pointer; }
.tag-link:hover { border-color: var(--accent); }
.tag-link, .tag-x { display: inline-flex; align-items: center; height: 29px; }
.tag-link { gap: 7px; }
.tag-count { color: var(--faint); }
.tag-x { border-left: none; width: 29px; padding: 0; justify-content: center; color: var(--accent); }
.tag-x:hover { background: var(--accent-dim); }
.editor { position: relative; margin-top: 12px; }
.editor[hidden] { display: none; }
.editor input { flex: 1; background: transparent; border: none; outline: none; padding: 10px 12px; font-size: 13px; min-width: 0; caret-color: var(--accent); }
.editor .go { padding: 0 16px; font-size: 11px; }
.editor .hint { margin-top: .6rem; white-space: normal; }

@media (max-width: 860px) {
  header { grid-template-columns: 1fr; gap: 1.25rem; }
  .brand { padding-top: 0; }
  .app { height: auto; container-type: normal; }
  .wrap { width: auto; height: auto; padding: 16px; }
  header { height: auto; }
  .hint { white-space: normal; }
  .toolbar { height: auto; flex-wrap: wrap; padding: 6px 0 6px 1rem; }
  .grid { grid-template-columns: repeat(4, minmax(0, 1fr)); grid-template-rows: none; grid-auto-rows: auto; gap: 3px; }
  .viewer { grid-template-columns: 1fr; grid-template-rows: auto auto; overflow-y: auto; }
  /* min-height: auto: the phone viewer scrolls (image on top, info below), so the image area keeps its height.
     With the desktop min-height: 0 the grid squeezed it to fit the screen, the link around the image capped its
     height to that, the width didn't follow, and the box (and the loading color in it) got wider than the picture */
  .stage { padding: 16px 56px; min-height: auto; }
  .stage img { cursor: default; max-height: 68dvh; }
  .stage video { max-height: 68dvh; }
  .panel { border-left: none; border-top: 1px solid var(--line-soft); overflow: visible; }
}

/* ---------- added for the backend version ---------- */
#chips { display: contents; }
/* header buttons line up exactly with the search bar: same top, same 33px height */
.account { justify-self: end; display: flex; gap: 8px; }
.account .go, .account .btn { height: 33px; }
.btn { height: 31px; padding: 0 14px; background: var(--surface); border: 1px solid var(--line); font-family: var(--mono); font-size: 12px; cursor: pointer; }
.btn:hover { background: var(--surface-2); border-color: var(--faint); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.meta input[type="date"] { background: var(--surface); border: 1px solid var(--line); padding: 2px 6px; font-family: var(--mono); font-size: 12px; color-scheme: dark light; }
.admin-actions { display: flex; justify-content: space-between; gap: 18px; margin-top: auto; padding-top: 12px; border-top: 1px solid var(--line-soft); }
/* the same line above the set thumbnails and the tags; no line for a media without a set */
.panel-sep { padding-top: 12px; border-top: 1px solid var(--line-soft); }
.panel-sep:empty { display: none; }
.text-btn.danger { color: var(--muted); }
.text-btn.danger:hover { color: var(--accent); }
#vImg.pending { visibility: hidden; }
/* while the next media's details load, the panel shows nothing instead of the previous media's */
.viewer.loading .panel > :not(.panel-head) { visibility: hidden; }

.modal { position: fixed; inset: 0; z-index: 40; background: rgba(0, 0, 0, .6); display: flex; align-items: center; justify-content: center; padding: 16px; }
.modal[hidden] { display: none; }
.modal-box { width: min(440px, 100%); max-height: 100%; overflow-y: auto; background: var(--surface); border: 1px solid var(--line); border-left: 2px solid var(--accent); padding: 24px; display: flex; flex-direction: column; gap: 14px; }
.modal-box h2 { font-size: 18px; font-weight: 500; letter-spacing: -0.01em; }
.modal-box label { display: flex; flex-direction: column; gap: 6px; font-family: var(--sans); font-size: 12px; color: var(--faint); }
.modal-box input, .modal-box select { background: var(--bg); border: 1px solid var(--line); padding: 8px 10px; font-family: var(--mono); font-size: 13px; color: var(--text); outline: none; min-width: 0; }
.modal-box input:focus, .modal-box select:focus { border-color: var(--faint); }
.modal-box input[type="file"] { padding: 6px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }
.modal-actions .go { height: 31px; }
.note { font-family: var(--sans); font-weight: 300; font-size: 12px; line-height: 1.6; color: var(--faint); }
.note code { font-family: var(--mono); color: var(--muted); white-space: nowrap; }
.form-error { font-size: 12px; color: var(--accent); min-height: 1em; white-space: pre-line; }
.form-error:empty { display: none; }

/* ---------- prefixed tags: name:, author:, source: ---------- */
:root { --tp-name-bg: #f8dccd; --tp-name-fg: #7a3416; --tp-author-bg: #f3e4c6; --tp-author-fg: #6b4a12;
        --tp-source-bg: #dde3f6; --tp-source-fg: #2c3d78; --tp-other-bg: #e6e6e6; --tp-other-fg: #555; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --tp-name-bg: #4f2918; --tp-name-fg: #f5c4ab; --tp-author-bg: #4a3816; --tp-author-fg: #f0d6a6;
        --tp-source-bg: #26315a; --tp-source-fg: #c9d3f5; --tp-other-bg: #262626; --tp-other-fg: #a8a5a0; }
}
:root[data-theme="dark"] { --tp-name-bg: #4f2918; --tp-name-fg: #f5c4ab; --tp-author-bg: #4a3816; --tp-author-fg: #f0d6a6;
      --tp-source-bg: #26315a; --tp-source-fg: #c9d3f5; --tp-other-bg: #262626; --tp-other-fg: #a8a5a0; }
.tagtext { display: inline-flex; align-items: center; }
/* 17px tall: fits the 25px chips and 29px tags on whole pixels. Plex sits low, so 1px more room below */
.tp { font-size: 10px; line-height: 1; padding: 3px 5px 4px; margin-right: 6px; }
.tp-name { background: var(--tp-name-bg); color: var(--tp-name-fg); }
.tp-author { background: var(--tp-author-bg); color: var(--tp-author-fg); }
.tp-source { background: var(--tp-source-bg); color: var(--tp-source-fg); }
.tp-other { background: var(--tp-other-bg); color: var(--tp-other-fg); }

/* ---------- toolbar + manage mode ---------- */
.toolbar .tb { display: flex; justify-content: space-between; align-items: center; gap: 1rem; width: 100%; min-width: 0; }
.toolbar .tb[hidden] { display: none; }
#tbManage .controls { gap: 6px; align-items: center; overflow-x: auto; }
/* the script snaps each separator onto one whole screen pixel (see snapSeparators), so it stays thin at any scaling */
.sep { width: 1px; height: 18px; background: var(--line); margin: 0 6px; flex: none; }
.btn.small, .go.small { height: 26px; padding: 0 10px; font-size: 11px; flex: none; }
.btn:disabled { opacity: .35; cursor: default; background: var(--surface); border-color: var(--line); }
.btn.danger:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
body.managing .grid { user-select: none; }
body.managing .tile { cursor: pointer; }
.tile .check { position: absolute; top: 8px; right: 8px; width: 18px; height: 18px; border: 1px solid rgba(240,237,230,.75); background: rgba(13,13,13,.55); }
/* selection frames sit exactly on the tile edge, 2px inward on every side */
.tile.selected::after, .tile.pending::after { content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 1; }
.tile.selected::after { border: 2px solid var(--accent); }
.tile.selected .check { border-color: var(--accent);
  /* checkmark drawn centered in a 16x16 box, so it sits in the middle on every side */
  background: var(--accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.2l3 3 6-6.4' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 12px 12px no-repeat; }
.tile.pending::after { border: 2px dashed var(--faint); }
.tile .check, .tile .badges { z-index: 2; }
.selbox { position: fixed; z-index: 30; border: 1px solid var(--accent); background: rgba(217, 65, 98, .12); pointer-events: none; }

/* ---------- dialogs ---------- */
.modal-box.wide { width: min(760px, 100%); }
.modal-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.field-label { font-family: var(--sans); font-size: 12px; color: var(--faint); margin-bottom: 6px; }
.opt-label { opacity: .6; margin-left: 4px; }
.chipfield-wrap { position: relative; }
.chips { display: contents; }
.modal-box .field input { background: transparent; border: none; padding: 5px 2px; }
.modal-box .plain-input { width: 100%; }
.go.danger-go { background: var(--accent); }

.drop { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 28px 16px; border: 1px dashed var(--line); background: var(--bg); cursor: pointer; text-align: center; }
.modal-box .drop { gap: 6px; }
.drop:hover, .drop.over { border-color: var(--accent); }
.drop:focus-within { outline: none; border-color: var(--accent); }  /* the dashed border itself is the highlight */
.drop-main { font-family: var(--mono); font-size: 13px; color: var(--text); }
.drop-sub { font-family: var(--sans); font-weight: 300; font-size: 12px; color: var(--faint); }

.up-list { list-style: none; max-height: 264px; overflow-y: auto; border: 1px solid var(--line-soft); }
.up-list[hidden] { display: none; }
.up-item { display: grid; grid-template-columns: 22px 52px minmax(0, 1fr) auto auto; gap: 12px; align-items: center; padding: 8px 10px; border-bottom: 1px solid var(--line-soft); }
.up-item:last-child { border-bottom: none; }
.up-item img { width: 52px; height: 52px; object-fit: cover; display: block; background: var(--bg); }
.modal-box .up-title { width: 100%; background: transparent; border: 1px solid transparent; padding: 4px 6px; font-size: 13px; }
.modal-box .up-title:hover, .modal-box .up-title:focus { border-color: var(--line); }
.up-meta { font-family: var(--sans); font-size: 11px; color: var(--faint); padding-left: 7px; margin-top: 2px; white-space: pre; overflow: hidden; text-overflow: ellipsis; }
.up-err { font-size: 11px; color: var(--accent); padding-left: 7px; margin-top: 2px; }
.up-state { font-size: 11px; color: var(--faint); min-width: 7ch; text-align: right; }
.up-item.busy .up-state { color: var(--text); }
.up-item.done .up-state { color: #5cb85c; }
.up-item.failed .up-state { color: var(--accent); }
.up-remove { width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; padding: 0; background: none; border: none; color: var(--faint); cursor: pointer; }
.up-remove:hover:not(:disabled) { color: var(--accent); }
.up-remove:disabled { opacity: .3; cursor: default; }
.up-fields { display: flex; flex-direction: column; gap: 14px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.up-summary { margin-right: auto; align-self: center; font-size: 12px; color: var(--faint); }

.seg { display: flex; border: 1px solid var(--line); }
.seg button { flex: 1; height: 34px; background: var(--bg); border: none; border-right: 1px solid var(--line); font-family: var(--mono); font-size: 12px; color: var(--muted); cursor: pointer; }
.seg button:last-child { border-right: none; }
.seg button:hover { background: var(--surface-2); color: var(--text); }
.seg button[aria-checked="true"] { background: var(--accent); color: #fff; }
.seg button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

@media (max-width: 860px) {
  .field-row { grid-template-columns: 1fr; }
}

/* upload list ordering */
.up-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; margin-bottom: -6px; font-size: 12px; color: var(--text); }
.up-head[hidden] { display: none; }
.up-hint { font-family: var(--sans); font-weight: 300; color: var(--faint); }
.up-handle { width: 22px; height: 40px; padding: 0; display: flex; align-items: center; justify-content: center; background: none; border: none; color: var(--faint); cursor: grab; }
.up-handle svg { fill: currentColor; display: block; }
.up-handle:hover:not(:disabled) { color: var(--text); }
.up-handle:disabled { cursor: default; opacity: .25; }
.up-handle:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.up-list.single .up-item { grid-template-columns: 52px minmax(0, 1fr) auto auto; }
.up-item.dragging { opacity: .4; }
.up-item.drop-before { box-shadow: inset 0 2px 0 var(--accent); }
.up-item.drop-after { box-shadow: inset 0 -2px 0 var(--accent); }

.up-slug { font-family: var(--mono); font-size: 13px; color: var(--text); padding-left: 7px; user-select: all; }

/* sets as an offset card deck: the cover sits bottom left, page 2 peeks out top right */
.tile.deck, .tile.deck.hidden { background: none; }
.tile.deck .card { position: absolute; overflow: hidden; background: var(--surface); outline: 2px solid var(--bg); }
.tile.deck .card img { width: 100%; height: 100%; object-fit: cover; display: block; }
.deck-2 .card { width: 91%; height: 91%; }
.deck-2 .front { left: 0; bottom: 0; }
.deck-2 .back-1 { right: 0; top: 0; }
/* each card of a deck shows the checkerboard on its own when that page is hidden or private */
.tile.deck.hidden .card.back img { opacity: 1; }
.tile.deck.hidden .card.front, .tile.deck .card.hidden-card { background-color: var(--checker-a); background-image: conic-gradient(var(--checker-b) 25%, transparent 0 50%, var(--checker-b) 0 75%, transparent 0); background-size: 24px 24px; background-attachment: fixed; }
.tile.deck .card.hidden-card img, .tile.deck.hidden .card.back.hidden-card img { opacity: .5; }

/* the viewer image links to the original file */
.stage .source { display: flex; max-width: 100%; max-height: 100%; cursor: zoom-in; }
.stage .source img { cursor: zoom-in; }
.stage .source:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.stage .source[hidden] { display: none; }  /* the display: flex above would otherwise beat the attribute */

/* the Search button covers the bar's 1px border, so it's as tall as the header buttons (33px) */
.search .input-row .go { margin: -1px -1px -1px 0; }
/* Search, Upload, Log in and Log out share one size */
#go, .account .go, .account .btn { min-width: 80px; }

/* page numbers: Plex Mono keeps room above digits for tall letters, so true center looks low.
   1.5px bottom padding lifts the digits into the optical middle. Arrows are SVG, centered exactly. */
.pager button { display: inline-flex; align-items: center; justify-content: center; padding: 0 0 1.5px; }
#pPrev, #pNext, .nav { padding: 0; display: inline-flex; align-items: center; justify-content: center; }
.chev { display: block; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.nav .chev { width: 16px; height: 16px; }

/* snap the grid to whole pixels: half-pixel tiles blur every edge and make 2px frames look uneven */
@supports (width: round(down, 10.5px, 1px)) {
  .wrap {
    --s: round(down, max(90px, min((100cqw - 2 * var(--pad) - 7 * var(--gap)) / 8, (100cqh - var(--chrome) - 3 * var(--gap)) / 4)), 1px);
    margin: 0;
    margin-left: round(down, (100cqw - (8 * var(--s) + 7 * var(--gap))) / 2, 1px);
  }
  @media (max-width: 860px) { .wrap { margin-left: 0; } }
}


/* manage mode: a colored stripe along the bottom marks which set a page belongs to */
.tile .setmark { position: absolute; left: 0; right: 0; bottom: 0; height: 4px; z-index: 2; pointer-events: none; }
.tile.selected .setmark { left: 2px; right: 2px; bottom: 2px; }  /* sits inside the pink selection frame */

/* set markers beyond 8 sets: the same colors as diagonal stripes, 4px tall */
.setmark.set-solid { background: var(--set-color); }
.setmark.set-diag { background: repeating-linear-gradient(45deg, var(--set-color) 0 3px, var(--bg) 3px 6px); }

/* pager row: off-page selection tray on the left, page numbers centered, empty right side */
.pager-row { flex: none; height: 28px; margin-top: 12px; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; }
.pager-row .pager { margin-top: 0; grid-column: 2; }  /* fixed column, also when the tray is hidden */
.tray { grid-column: 1; position: relative; display: flex; align-items: center; gap: 4px; justify-self: start; }
.tray[hidden] { display: none; }
.tray-label { height: 28px; padding: 0 8px 0 0; background: none; border: none; font-family: var(--sans); font-size: 11px; color: var(--faint); cursor: pointer; }
.tray-label:hover { color: var(--text); }
.mini { position: relative; width: 28px; height: 28px; padding: 0; border: none; background: var(--surface); cursor: pointer; overflow: hidden; }
.mini img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mini::after { content: ''; position: absolute; inset: 0; border: 1px solid var(--accent); pointer-events: none; }
.mini .pg-no { position: absolute; right: 0; bottom: 0; font-size: 8px; line-height: 1; padding: 1px 2px; background: rgba(13,13,13,.85); color: #f0ede6; }
.mini.elsewhere img { opacity: .4; }
.tray-more { height: 28px; min-width: 28px; padding: 0 6px; border: 1px solid var(--line); background: var(--surface); font-family: var(--mono); font-size: 11px; color: var(--text); cursor: pointer; }
.tray-more:hover, .mini:hover::after { border-color: var(--faint); }
.mini:focus-visible, .tray-more:focus-visible, .tray-label:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tray-pop { position: absolute; left: 0; bottom: calc(100% + 8px); z-index: 15; width: 320px; max-height: 340px; overflow-y: auto; background: var(--surface); border: 1px solid var(--line); padding: 12px; display: flex; flex-direction: column; gap: 12px; }
.tray-pop[hidden] { display: none; }
.tray-pop h4 { font-family: var(--sans); font-weight: 400; font-size: 11px; color: var(--faint); margin-bottom: 6px; display: flex; justify-content: space-between; }
.tray-pop h4 button { background: none; border: none; font-family: var(--mono); font-size: 11px; color: var(--accent); cursor: pointer; padding: 0; }
.tray-group { display: flex; flex-wrap: wrap; gap: 4px; }
.tray-item { position: relative; width: 44px; height: 44px; }
.tray-item .mini { width: 44px; height: 44px; }
.tray-item .unsel { position: absolute; top: 2px; right: 2px; width: 16px; height: 16px; padding: 0; display: inline-flex; align-items: center; justify-content: center; background: rgba(13,13,13,.85); border: none; color: #f0ede6; cursor: pointer; }
.tray-item .unsel:hover { color: var(--accent); }

/* type: tags (type:comic) get their own label color */
:root { --tp-type-bg: #ead9f2; --tp-type-fg: #5b2a73; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --tp-type-bg: #3d2650; --tp-type-fg: #e2c6f2; } }
:root[data-theme="dark"] { --tp-type-bg: #3d2650; --tp-type-fg: #e2c6f2; }
.tp-type { background: var(--tp-type-bg); color: var(--tp-type-fg); }

/* comic cover in the viewer */
.set-actions { display: flex; align-items: center; gap: 0; }
.is-cover { font-size: 12px; color: var(--faint); }
.strip button.cover::before { content: 'cover'; position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; font-size: 9px; line-height: 1; padding: 2px 0 3px; text-align: center; background: rgba(13,13,13,.85); color: #f0ede6; }

/* reorder dialog: all pages as a grid, drag into place */
.modal-box.wide { width: min(760px, 100%); }
.ro-grid { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, 96px); gap: 8px; max-height: 52vh; overflow-y: auto; padding: 2px; }
.ro-item { position: relative; width: 96px; height: 96px; cursor: grab; background: var(--bg); }
.ro-item img { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; }
.ro-item::after { content: ''; position: absolute; inset: 0; border: 1px solid var(--line); pointer-events: none; }
.ro-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ro-item.dragging { opacity: .4; }
.ro-item.drop-before { box-shadow: -5px 0 0 -1px var(--accent); }
.ro-item.drop-after { box-shadow: 5px 0 0 -1px var(--accent); }
.ro-no { position: absolute; left: 4px; top: 4px; display: inline-flex; align-items: center; height: 18px; padding: 0 6px; font-size: 11px; line-height: 1; background: rgba(13,13,13,.85); color: #f0ede6; }
.ro-cover { position: absolute; left: 0; right: 0; bottom: 0; font-size: 9px; line-height: 1; padding: 2px 0 3px; text-align: center; background: rgba(13,13,13,.85); color: #f0ede6; }

/* page position in the viewer: big, top left of the panel */
.v-page { font-size: 24px; font-weight: 500; letter-spacing: -0.02em; color: var(--text); font-variant-numeric: tabular-nums; }
.set-actions { margin-left: auto; }
#vSet .row-head { justify-content: flex-end; margin-bottom: 10px; }  /* same gap the old heading had */
/* dialogs focused as a whole (upload) show no outline */
.modal-box:focus { outline: none; }
/* reorder dialog: as wide as its pages */
.modal-box.fit { width: auto; max-width: min(760px, 100%); }

/* strip: the frame (gray, or pink for the current page) always on top; the cover label sits inside it, never under it */
.strip button::after { z-index: 2; }
.strip button.cover::before { left: 1px; right: 1px; bottom: 1px; }
.strip button.cover.current::before { left: 2px; right: 2px; bottom: 2px; }

/* separators between the viewer's set actions */
.sep.small { height: 12px; margin: 0 10px; }

/* drag-unselect preview: the pink frame turns into a dashed gray one before it's dropped */
.tile.pending-off::after { content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 1; border: 2px dashed var(--faint); }
.tile.pending-off .check { opacity: .4; }

/* error pages (404 and friends): "cora" top left like the header, the message as a left-aligned block
   in the middle of the screen */
body.error-page { min-height: 100%; display: flex; align-items: center; justify-content: center; padding: 20px 24px; }
.error-page .brand { position: absolute; top: calc(20px + env(safe-area-inset-top, 0px)); left: 24px; padding: 0; }
.error-box { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; max-width: 460px; }
.error-code { font-size: 12px; color: var(--faint); }
.error-title { font-size: 28px; font-weight: 500; letter-spacing: -0.02em; line-height: 1.15; }
.error-text { font-family: var(--sans); font-weight: 300; font-size: 13px; line-height: 1.7; color: var(--muted); }
.error-home { display: inline-flex; align-items: center; height: 33px; min-width: 80px; margin-top: 14px; text-decoration: none; }

/* Edit media dialog: current image next to the replacement */
.em-row { display: grid; grid-template-columns: 160px auto 160px; align-items: center; gap: 14px; }
.em-cell { display: flex; flex-direction: column; gap: 6px; }
.em-cap { font-family: var(--sans); font-size: 11px; color: var(--faint); }
.em-img { width: 160px; height: 160px; object-fit: cover; display: block; background: var(--bg); }
.em-arrow { color: var(--faint); }
.em-arrow svg { display: block; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.em-drop { position: relative; width: 160px; height: 160px; display: flex; align-items: center; justify-content: center; text-align: center; padding: 12px; border: 1px dashed var(--line); background: var(--bg); cursor: pointer; font-family: var(--sans); font-size: 11px; line-height: 1.5; color: var(--faint); }
.em-drop:hover, .em-drop.over { border-color: var(--accent); }
.em-drop img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.em-meta { font-family: var(--sans); font-size: 11px; color: var(--faint); min-height: 1em; }

/* until the script has started, the hub stays invisible: after a reload on #id the viewer covers it first */
body:not(.ready) .app { visibility: hidden; }
.viewer:focus { outline: none; }

/* pink buttons that can't be used yet (Upload without files, Replace without an image) look greyed out */
.go:disabled, .go:disabled:hover { background: var(--accent); opacity: .35; cursor: default; }

/* ---------- first setup page ---------- */
body.setup { min-height: 100%; display: flex; flex-direction: column; padding: 20px 32px; }
.setup-head { flex: none; }
.modal-box.setup-box { width: min(500px, 100%); }
.setup-main { flex: 1; display: flex; align-items: center; justify-content: center; padding: 40px 0; }
.setup-box form, .setup-box [data-step] { display: flex; flex-direction: column; gap: 14px; }
.setup-box [hidden] { display: none; }
.steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; }
.steps span { height: 3px; background: var(--line); }
.steps span.done { background: var(--accent-dim); }
.steps span.on { background: var(--accent); }
.setup-title { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.setup-title span { font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
.code-input { font-size: 15px !important; letter-spacing: 0.12em; }
.setup-box input::placeholder { color: var(--dim); }
.modal-box input[aria-invalid="true"] { border-color: var(--accent); }
.cmd-field { display: flex; flex-direction: column; gap: 6px; font-family: var(--sans); font-size: 12px; color: var(--faint); }
.cmd { display: flex; align-items: stretch; min-width: 0; background: var(--bg); border: 1px solid var(--line-soft); }
.cmd code { flex: 1; min-width: 0; padding: 8px 10px; font-family: var(--mono); font-size: 12px; color: var(--dim);
            overflow-x: auto; white-space: nowrap; transition: color .15s; }
.cmd:hover, .cmd:focus-within { border-color: var(--line); }
.cmd:hover code, .cmd:focus-within code { color: var(--muted); }
.cmd button { flex: none; padding: 0 12px; background: var(--surface); border: none; border-left: 1px solid var(--line-soft);
              font-family: var(--mono); font-size: 11px; color: var(--muted); cursor: pointer; }
.cmd button:hover { color: var(--text); }
.cmd button.copied { color: var(--accent); }
.cmd button:focus-visible, .setup-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.setup-link { height: 31px; display: inline-flex; align-items: center; text-decoration: none; }
@media (max-width: 520px) { body.setup { padding: 16px; } .setup-main { padding: 24px 0; } }

/* copy link in the preview header: an icon button beside close, the admin's menu below it */
.head-actions { display: flex; align-items: center; gap: 8px; }
.copy-wrap { position: relative; display: flex; }
.icon-btn { flex: none; width: 34px; height: 34px; display: flex; align-items: center; justify-content: center; padding: 0;
            background: none; border: 1px solid var(--line); color: var(--text); cursor: pointer; }
.icon-btn svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: square; }
.icon-btn:hover, .icon-btn[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }
.icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.icon-btn .ic-check, .icon-btn.copied .ic-link { display: none; }
.icon-btn.copied .ic-check { display: block; }
.icon-btn.copied { border-color: var(--accent); color: var(--accent); }
.copied-label { font-size: 11px; color: var(--accent); }
.copy-menu { position: absolute; top: calc(100% + 6px); right: 0; z-index: 5; min-width: 220px; display: flex; flex-direction: column;
             background: var(--surface); border: 1px solid var(--line); }
.copy-menu[hidden] { display: none; }
.copy-menu button { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 8px 12px; background: none; border: none;
                    font-family: var(--mono); font-size: 12px; color: var(--text); text-align: left; cursor: pointer; }
.copy-menu button + button { border-top: 1px solid var(--line-soft); }
.copy-menu button span { font-family: var(--sans); font-weight: 300; font-size: 11px; color: var(--faint); }
.copy-menu button:hover:not(:disabled), .copy-menu button:focus-visible { background: var(--bg); outline: none; }
.copy-menu button:focus-visible { box-shadow: inset 2px 0 0 var(--accent); }
.copy-menu button:disabled { color: var(--faint); cursor: not-allowed; }

/* phones: 7 page slots (see pageSlots) and, below 420px, slimmer buttons, so the pager never makes the page
   wider than the screen (which shifted the whole layout) */
@media (max-width: 420px) {
  .pager { gap: 8px; }
  .nums { gap: 3px; }
  .pager button, .nums .gap { width: 32px; }
}

/* login dialog: one full-width button per account service, icon left of the label */
.oauth-list { display: flex; flex-direction: column; gap: 8px; }
.oauth-btn { display: flex; align-items: center; gap: 12px; width: 100%; height: 42px; padding: 0 14px;
             background: var(--surface); border: 1px solid var(--line); color: var(--text);
             font-family: var(--mono); font-size: 12px; text-align: left; cursor: pointer; }
.oauth-btn:hover:not(:disabled) { background: var(--surface-2); border-color: var(--faint); }
.oauth-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.oauth-btn:disabled { opacity: .4; cursor: not-allowed; }
.oauth-icon { flex: none; width: 18px; height: 18px; }
.oauth-or { display: flex; align-items: center; gap: 10px; margin: 2px 0; font-family: var(--sans); font-size: 11px; color: var(--faint); }
.oauth-or::before, .oauth-or::after { content: ""; flex: 1; border-top: 1px solid var(--line-soft); }

/* icons inside buttons never take the click themselves: it always goes to the button */
button svg { pointer-events: none; }
