/* Fan Arch Graphics
   Dark editor chrome, deliberately quiet so the artwork is the only thing
   that shouts. Type is Inter for the UI; the brand condensed face is reserved
   for the canvas itself. */

@font-face {
  font-family: 'FanArchCondensed';
  src: url('/fonts/FanArchCondensed.otf') format('opentype');
  font-weight: normal;
  font-style: normal;
  font-display: block;
}

:root {
  --bg:        #0b0d12;
  --panel:     #12151d;
  --panel-2:   #191d28;
  --panel-3:   #222839;
  --line:      #262d3d;
  --line-soft: #1d2331;
  --text:      #eef1f7;
  --muted:     #8b96ad;
  --dim:       #626d84;
  --accent:    #e23b3b;
  --accent-2:  #ff5757;
  --accent-soft: rgba(226, 59, 59, .15);
  --focus:     #4c8dff;
  --good:      #3ec98a;
  --warn:      #f0c04c;
  --r-sm: 8px;
  --r:    11px;
  --r-lg: 16px;
  --ui: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --shadow: 0 18px 44px rgba(0, 0, 0, .5);
}

* { box-sizing: border-box; }
html, body {
  margin: 0; height: 100%;
  background: var(--bg); color: var(--text);
  font-family: var(--ui); font-size: 13.5px;
  -webkit-font-smoothing: antialiased;
}
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: var(--focus); }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #262d3d; border-radius: 6px; border: 2px solid var(--panel); }
::-webkit-scrollbar-thumb:hover { background: #333d52; }

/* ---------------------------------------------------------- primitives */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--panel-2);
  font-weight: 550; letter-spacing: -.005em;
  transition: background .12s, border-color .12s, transform .06s, opacity .12s;
  white-space: nowrap;
}
.btn:hover { background: var(--panel-3); border-color: #36405a; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .35; cursor: not-allowed; }
.btn:disabled:hover { background: var(--panel-2); border-color: var(--line); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-2); border-color: var(--accent-2); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn-ghost:hover { background: var(--panel-2); color: var(--text); }
.btn-danger:hover { background: rgba(226, 59, 59, .18); border-color: rgba(226, 59, 59, .5); color: #ff9a9a; }
.btn-sm { padding: 6px 10px; font-size: 12.5px; }
.btn-icon { padding: 0; width: 34px; height: 34px; }
.btn-block { width: 100%; }
.btn.on { background: var(--accent); border-color: var(--accent); color: #fff; }

.input {
  width: 100%; padding: 10px 12px;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: var(--r); outline: none;
  transition: border-color .12s, box-shadow .12s;
}
.input:focus { border-color: var(--focus); box-shadow: 0 0 0 3px rgba(76, 141, 255, .17); }
.input::placeholder { color: var(--dim); }

.field { display: block; margin-bottom: 14px; }
.field > span {
  display: block; margin-bottom: 6px; color: var(--muted);
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em;
}

.alert {
  padding: 11px 13px; border-radius: var(--r); margin-bottom: 14px;
  background: var(--accent-soft); border: 1px solid rgba(226, 59, 59, .38);
  color: #ffb0b0; font-size: 13px; line-height: 1.5;
}
.alert:empty { display: none; }
.alert.ok { background: rgba(62, 201, 138, .13); border-color: rgba(62, 201, 138, .38); color: #a5f0cb; }

.panel-hint { margin: 0 0 14px; color: var(--muted); font-size: 12.5px; line-height: 1.55; }
.panel-title { margin: 0 0 5px; font-size: 11px; font-weight: 650;
               text-transform: uppercase; letter-spacing: .09em; color: var(--dim); }

/* fan-arch-logo.png is cropped tight to the mark (1200x238), so these heights
   are the height of the visible logo, not of a box mostly full of padding. */
.logo { height: 26px; width: auto; display: block; }
.logo-lg { height: 34px; }

/* ---------------------------------------------------------------- login */

.auth-wrap { min-height: 100%; display: grid; place-items: center; padding: 24px;
  background: radial-gradient(900px 500px at 50% -10%, #1a1f2c 0%, var(--bg) 65%); }
.auth-card {
  width: 100%; max-width: 380px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 18px; padding: 34px; box-shadow: var(--shadow);
}
.auth-brand { text-align: center; margin-bottom: 26px; }
.auth-brand img { height: 44px; margin: 0 auto 14px; display: block; }
.auth-brand h1 { margin: 0; font-size: 18px; letter-spacing: -.015em; }
.auth-brand p { margin: 6px 0 0; color: var(--muted); font-size: 13px; }

/* --------------------------------------------------------------- editor */

/* Flex, not grid: the admin banner is only in the DOM some of the time, and a
   display:none child does not hold a grid row - which silently shifted every
   row up and collapsed the canvas. */
.app { display: flex; flex-direction: column; height: 100%; }
.app > .acting-banner { flex: 0 0 auto; }
.app > .topbar { flex: 0 0 56px; }
.app > .workspace { flex: 1 1 auto; min-height: 0; }

.acting-banner {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 16px; font-size: 12.5px; font-weight: 550;
  background: linear-gradient(90deg, #4a2a08, #3a2410);
  border-bottom: 1px solid #6b4413; color: #ffd79a;
}
.acting-banner .spacer { flex: 1; }
.acting-banner strong { color: #fff; }

.topbar {
  display: flex; align-items: center; gap: 12px; padding: 0 14px;
  background: var(--panel); border-bottom: 1px solid var(--line);
}
.topbar .show-name { font-weight: 620; letter-spacing: -.01em; font-size: 14px; }
.topbar .divider { width: 1px; height: 22px; background: var(--line); }
.topbar .spacer { flex: 1; }
.save-state { color: var(--dim); font-size: 12px; min-width: 108px; text-align: right; }
.save-state.saving { color: var(--warn); }
.save-state.saved  { color: var(--good); }
.save-state.error  { color: #ff8a8a; }

.workspace { display: grid; grid-template-columns: 296px 1fr; min-height: 0; }

.side { background: var(--panel); border-right: 1px solid var(--line);
        display: grid; grid-template-rows: auto 1fr; min-height: 0; }
.tabs { display: flex; padding: 0 8px; border-bottom: 1px solid var(--line); }
.tab {
  flex: 1; padding: 13px 6px 11px; background: none; border: none;
  color: var(--muted); font-weight: 600; font-size: 12.5px;
  border-bottom: 2px solid transparent; transition: color .12s;
}
.tab:hover { color: var(--text); }
.tab[aria-selected="true"] { color: var(--text); border-bottom-color: var(--accent); }
.tab-panels { overflow-y: auto; min-height: 0; }
.tab-panel { display: none; padding: 16px; }
.tab-panel.active { display: block; }

/* uploads */
.dropzone {
  border: 1.5px dashed var(--line); border-radius: 13px;
  padding: 24px 14px; text-align: center; color: var(--muted);
  background: var(--panel-2); margin-bottom: 14px;
  font-size: 12.5px; line-height: 1.6; transition: border-color .12s, background .12s;
}
.dropzone.hot { border-color: var(--accent); background: var(--accent-soft); color: var(--text); }
.dropzone strong { color: var(--text); display: block; margin-bottom: 5px; font-size: 13.5px; }

.asset-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.asset { border: 1px solid var(--line); border-radius: 11px; overflow: hidden;
         background: var(--panel-2); position: relative; }
.asset .thumb { height: 76px; display: grid; place-items: center; overflow: hidden;
  background-color: #0e121a;
  background-image:
    linear-gradient(45deg, #1a2029 25%, transparent 25%),
    linear-gradient(-45deg, #1a2029 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #1a2029 75%),
    linear-gradient(-45deg, transparent 75%, #1a2029 75%);
  background-size: 12px 12px;
  background-position: 0 0, 0 6px, 6px -6px, -6px 0;
}
.asset .thumb img { max-width: 100%; max-height: 100%; display: block; }
.asset .name { padding: 6px 8px 4px; font-size: 11px; color: var(--muted);
               white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.asset .actions { display: flex; gap: 4px; padding: 0 6px 6px; }
.asset .actions .btn { flex: 1; font-size: 11px; padding: 5px 4px; }
.asset .actions .btn-danger { flex: 0 0 auto; }
.asset.is-overlay { border-color: var(--accent); }
.asset .badge { position: absolute; top: 6px; left: 6px; background: var(--accent);
  color: #fff; font-size: 9.5px; font-weight: 700; padding: 2px 6px;
  border-radius: 5px; letter-spacing: .05em; }

/* layers */
.layer-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
/* A layer row IS the layer: the real words, or the real picture. A list of
   invented names ("Picture 1, Picture 2") tells nobody which is which. */
.layer {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  padding: 7px; border: 1.5px solid transparent; border-radius: 10px;
  background: var(--panel-2); cursor: pointer;
  transition: background .12s, border-color .12s;
}
.layer:hover { background: var(--panel-3); }
.layer.selected { border-color: var(--focus); background: rgba(76, 141, 255, .14); }
.layer.is-locked { opacity: .68; }
.layer .lock { font-size: 11px; opacity: .75; flex: none; }

/* the words, set the way they actually read on the graphic */
.layer-text {
  flex: 1; min-width: 0;
  padding: 9px 11px; border-radius: 6px;
  background: rgba(255,255,255,.09);
  font-family: FanArchCondensed, system-ui, sans-serif;
  font-size: 14px; letter-spacing: .01em; line-height: 1.15;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.layer-text.is-headline { background: #f1f3f7; color: #111318; }
.layer-text.is-empty { opacity: .45; font-style: normal; }

/* a picture, shown as itself */
.layer-art {
  flex: 1; min-width: 0; height: 42px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 6px; overflow: hidden;
  background:
    linear-gradient(45deg, rgba(255,255,255,.06) 25%, transparent 25%, transparent 75%, rgba(255,255,255,.06) 75%),
    linear-gradient(45deg, rgba(255,255,255,.06) 25%, transparent 25%, transparent 75%, rgba(255,255,255,.06) 75%);
  background-size: 12px 12px;
  background-position: 0 0, 6px 6px;
}
.layer-art img { max-width: 100%; max-height: 42px; object-fit: contain; display: block; }
.layer-art.is-empty {
  color: var(--dim); font-size: 11.5px; font-family: inherit;
  background: rgba(255,255,255,.04);
}
.layer-order { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }

/* selected-layer panel */
.prop-head { display: flex; align-items: center; margin-bottom: 12px; }
.prop-head h2 { margin: 0; font-size: 15px; letter-spacing: -.01em; }
.prop-group { margin-top: 18px; }

/* colour picker */
.cp-section { margin-bottom: 16px; }
.cp-label { margin: 0 0 8px; font-size: 10.5px; font-weight: 650; letter-spacing: .09em;
            text-transform: uppercase; color: var(--dim); }
.cp-swatches { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.cp-swatch {
  aspect-ratio: 1; width: 100%; padding: 0; border-radius: 50%;
  border: 2px solid transparent; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .14);
  transition: transform .1s;
}
.cp-swatch.pale { box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .35); }
.cp-swatch:hover { transform: scale(1.12); }
.cp-swatch.selected { border-color: var(--focus); box-shadow: 0 0 0 2px rgba(76, 141, 255, .35); }

.cp-sv {
  position: relative; height: 116px; border-radius: 10px; margin-bottom: 10px;
  background: var(--hue, #f00); cursor: crosshair; touch-action: none;
  border: 1px solid var(--line-soft); overflow: hidden;
}
.cp-sv-white, .cp-sv-black { position: absolute; inset: 0; }
.cp-sv-white { background: linear-gradient(to right, #fff, rgba(255, 255, 255, 0)); }
.cp-sv-black { background: linear-gradient(to top, #000, rgba(0, 0, 0, 0)); }
.cp-sv-dot, .cp-hue-dot {
  position: absolute; width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid #fff; box-shadow: 0 1px 4px rgba(0, 0, 0, .6);
  transform: translate(-50%, -50%); pointer-events: none;
}
.cp-hue {
  position: relative; height: 12px; border-radius: 6px; cursor: pointer;
  touch-action: none; margin-bottom: 10px;
  background: linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00);
}
.cp-hue-dot { top: 50%; }
.cp-hex-row { display: flex; gap: 8px; align-items: center; }
.cp-preview { width: 34px; height: 34px; flex: 0 0 34px; border-radius: 9px;
              border: 1px solid var(--line); box-shadow: inset 0 0 0 1px rgba(255,255,255,.1); }
.cp-hex { text-transform: uppercase; letter-spacing: .04em; font-size: 12.5px; }
.cp-eyedrop { flex: 0 0 34px; font-size: 16px; }

/* canvas area */
.stage-area { display: grid; grid-template-rows: 1fr auto; min-height: 0;
  background: radial-gradient(1100px 560px at 50% -5%, #141926 0%, var(--bg) 68%); }
.stage-scroll { display: grid; place-items: center; padding: 16px; overflow: auto; min-height: 0; }
.stage-shell {
  position: relative; border-radius: 4px;
  background-color: #0d1017;
  background-image:
    linear-gradient(45deg, #161b25 25%, transparent 25%),
    linear-gradient(-45deg, #161b25 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #161b25 75%),
    linear-gradient(-45deg, transparent 75%, #161b25 75%);
  background-size: 24px 24px;
  background-position: 0 0, 0 12px, 12px -12px, -12px 0;
  box-shadow: 0 24px 64px rgba(0, 0, 0, .6);
  outline: 1px solid var(--line);
}
.stage-shell.drop-hot { outline: 2px solid var(--accent); }

#text-input {
  position: absolute; display: none; margin: 0; padding: 0;
  border: none; outline: 2px solid var(--focus); border-radius: 2px;
  background: rgba(8, 11, 18, .5); resize: none; overflow: hidden;
  font-family: 'FanArchCondensed', var(--ui);
}

.empty-overlay-note {
  position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%);
  text-align: center; color: var(--muted); font-size: 15px;
  pointer-events: none; padding: 0 40px; line-height: 1.6;
}

/* page strip */
.pages { position: relative; z-index: 3; border-top: 1px solid var(--line); background: var(--panel);
         padding: 11px 14px; display: flex; align-items: center; gap: 12px; }
.page-strip { display: flex; gap: 10px; overflow-x: auto; padding: 2px; flex: 1; }
.page-thumb {
  position: relative; flex: 0 0 auto; width: 122px; height: 70px; padding: 0;
  border: 2px solid var(--line); border-radius: 9px; overflow: hidden;
  background-color: #0d1017;
  background-image:
    linear-gradient(45deg, #161b25 25%, transparent 25%),
    linear-gradient(-45deg, #161b25 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #161b25 75%),
    linear-gradient(-45deg, transparent 75%, #161b25 75%);
  background-size: 10px 10px;
  background-position: 0 0, 0 5px, 5px -5px, -5px 0;
  transition: border-color .12s;
}
.page-thumb:hover { border-color: #3a4560; }
.page-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.page-thumb.current { border-color: var(--accent); }
.page-thumb .num { position: absolute; left: 4px; bottom: 3px; background: rgba(0, 0, 0, .72);
  color: #fff; font-size: 10px; font-weight: 700; padding: 1px 5px; border-radius: 4px; }
/* Deleting a page is one click with no confirm dialog, so the control has to
   read unmistakably as delete: a bin, and red the moment it is under the
   cursor. */
.page-thumb .kill { position: absolute; right: 4px; top: 4px; width: 24px; height: 24px;
  padding: 0; border: 1px solid rgba(255, 255, 255, .16); border-radius: 7px;
  background: rgba(10, 12, 18, .85); color: #fff; font-size: 12px;
  display: none; place-items: center; transition: background .12s, border-color .12s; }
.page-thumb:hover .kill { display: grid; }
.page-thumb .kill:hover { background: var(--accent); border-color: var(--accent); }
.page-actions { display: flex; gap: 8px; }

/* ---------------------------------------------------------------- admin */

.admin-wrap { max-width: 1060px; margin: 0 auto; padding: 28px 24px 72px; }
.admin-head { display: flex; align-items: center; gap: 14px; margin-bottom: 24px; }
.admin-head h1 { margin: 0; font-size: 19px; letter-spacing: -.015em; }
.admin-head .spacer { flex: 1; }
.card { background: var(--panel); border: 1px solid var(--line);
        border-radius: var(--r-lg); padding: 22px; margin-bottom: 20px; }
.card h2 { margin: 0 0 4px; font-size: 15px; letter-spacing: -.01em; }
.card .sub { margin: 0 0 18px; color: var(--muted); font-size: 12.5px; line-height: 1.55; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.checkbox { display: flex; align-items: center; gap: 9px; margin-bottom: 14px; color: var(--muted); }
.checkbox input { width: 16px; height: 16px; accent-color: var(--accent); }

.toolbar { display: flex; gap: 10px; align-items: center; margin-bottom: 16px; }
.toolbar .input { flex: 1; }
.count-pill { color: var(--dim); font-size: 12px; white-space: nowrap; }

.show-list { display: flex; flex-direction: column; gap: 10px; }
.show-row {
  display: grid; grid-template-columns: 128px 1fr auto; gap: 16px; align-items: center;
  padding: 12px; border: 1px solid var(--line); border-radius: 13px; background: var(--panel-2);
  transition: border-color .12s;
}
.show-row:hover { border-color: #36405a; }
.show-preview {
  width: 128px; height: 72px; border-radius: 8px; overflow: hidden; border: 1px solid var(--line);
  background-color: #0d1017;
  background-image:
    linear-gradient(45deg, #161b25 25%, transparent 25%),
    linear-gradient(-45deg, #161b25 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #161b25 75%),
    linear-gradient(-45deg, transparent 75%, #161b25 75%);
  background-size: 10px 10px; background-position: 0 0, 0 5px, 5px -5px, -5px 0;
  display: grid; place-items: center; cursor: pointer;
}
.show-preview img { width: 100%; height: 100%; object-fit: contain; }
.show-preview .none { color: var(--dim); font-size: 10.5px; text-align: center; padding: 4px; }
.show-meta h3 { margin: 0 0 3px; font-size: 14px; letter-spacing: -.01em; }
.show-meta .line { color: var(--muted); font-size: 12px; }
.show-meta .line b { color: var(--text); font-weight: 550; }
.show-actions { display: flex; gap: 7px; align-items: center; }
.tag { background: var(--accent-soft); color: #ff9d9d; border-radius: 5px;
       padding: 2px 6px; font-size: 10px; font-weight: 700; letter-spacing: .04em;
       vertical-align: middle; margin-left: 6px; }

/* modal */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(5, 7, 11, .8); backdrop-filter: blur(4px);
  display: grid; place-items: center; padding: 24px; z-index: 80;
}
/* [hidden] is a UA rule; an author display declaration outranks it, which is
   how this modal ended up open on page load. Say it explicitly. */
.modal-backdrop[hidden] { display: none; }
.modal { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow); width: 100%; max-width: 1000px; max-height: 90vh;
  display: grid; grid-template-rows: auto 1fr auto; overflow: hidden; }
.modal-head { display: flex; align-items: center; gap: 12px; padding: 16px 20px;
              border-bottom: 1px solid var(--line); }
.modal-head h2 { margin: 0; font-size: 15px; }
.modal-head .spacer { flex: 1; }
.modal-body { padding: 20px; overflow: auto; }
.modal-foot { padding: 14px 20px; border-top: 1px solid var(--line);
              display: flex; gap: 9px; justify-content: flex-end; }
.preview-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.preview-cell { border: 1px solid var(--line); border-radius: 11px; overflow: hidden;
  background-color: #0d1017;
  background-image:
    linear-gradient(45deg, #161b25 25%, transparent 25%),
    linear-gradient(-45deg, #161b25 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #161b25 75%),
    linear-gradient(-45deg, transparent 75%, #161b25 75%);
  background-size: 14px 14px; background-position: 0 0, 0 7px, 7px -7px, -7px 0;
}
.preview-cell { padding: 0; text-align: left; width: 100%; border-color: var(--line); }
.preview-cell:hover { border-color: var(--focus); }
.preview-cell img { width: 100%; display: block; }
.preview-cell .cap { display: flex; padding: 7px 10px; font-size: 11.5px; color: var(--muted);
                     background: var(--panel-2); border-top: 1px solid var(--line);
                     display: flex; justify-content: space-between; align-items: center; }

/* toast */
#toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%) translateY(14px);
  background: var(--panel-3); border: 1px solid var(--line); color: var(--text);
  padding: 11px 16px; border-radius: var(--r); font-size: 12.5px;
  box-shadow: var(--shadow); opacity: 0; pointer-events: none;
  transition: opacity .16s, transform .16s; z-index: 90; max-width: 440px; line-height: 1.5;
}
#toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
#toast.bad { border-color: rgba(226, 59, 59, .55); }

/* ----------------------------------------------------- admin: shell */

.admin-body { min-height: 100%; }
.admin-top {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 14px;
  padding: 0 20px; height: 60px;
  background: rgba(18, 21, 29, .92); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.admin-top .divider { width: 1px; height: 22px; background: var(--line); }
.admin-top .admin-title { font-weight: 620; letter-spacing: -.01em; }
.admin-top .spacer { flex: 1; }
.admin-nav { display: flex; gap: 4px; margin-left: 10px; }
.admin-tab {
  padding: 7px 14px; border: 1px solid transparent; border-radius: 999px;
  background: none; color: var(--muted); font-weight: 560; font-size: 13px;
  transition: background .12s, color .12s;
}
.admin-tab:hover { color: var(--text); background: var(--panel-2); }
.admin-tab[aria-selected="true"] { background: var(--panel-3); color: var(--text); border-color: var(--line); }

.admin-wrap { max-width: 1500px; margin: 0 auto; padding: 26px 24px 80px; }

.gallery-head { display: flex; align-items: flex-end; gap: 12px; margin-bottom: 6px; flex-wrap: wrap; }
.gallery-head h1 { margin: 0; font-size: 22px; letter-spacing: -.02em; }
.gallery-head .sub { margin: 5px 0 0; color: var(--muted); font-size: 13px; }
.gallery-head .spacer { flex: 1; }
.gallery-head .input { width: 280px; }
.count-pill { color: var(--dim); font-size: 12px; margin: 0 0 18px; }

/* ------------------------------------------------- admin: the gallery */


/* One card per show, packed tight. With 150 shows the job of this screen is
   to be scannable and fast to scroll, not spacious. */
.gallery-grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(228px, 1fr));
}
.show-card {
  border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
  background: var(--panel); position: relative;
  transition: border-color .12s, transform .1s, box-shadow .12s;
}
.show-card:hover {
  border-color: #3d4a63; transform: translateY(-2px);
  box-shadow: 0 12px 28px rgba(0, 0, 0, .45);
}
.show-card-cover {
  display: block; width: 100%; padding: 0; border: none;
  aspect-ratio: 16 / 9; position: relative; overflow: hidden;
  background-color: #0d1017;
  background-image:
    linear-gradient(45deg, #161b25 25%, transparent 25%),
    linear-gradient(-45deg, #161b25 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #161b25 75%),
    linear-gradient(-45deg, transparent 75%, #161b25 75%);
  background-size: 14px 14px; background-position: 0 0, 0 7px, 7px -7px, -7px 0;
}
.show-card-cover img { width: 100%; height: 100%; object-fit: contain; display: block; }
.show-card-count {
  position: absolute; right: 6px; top: 6px; z-index: 2;
  background: rgba(8, 10, 16, .82); color: #fff; font-size: 10px; font-weight: 650;
  padding: 3px 7px; border-radius: 999px; letter-spacing: .03em;
}
.show-card-empty {
  position: absolute; inset: 0; display: grid; place-items: center;
  color: var(--dim); font-size: 11.5px;
}
.show-card-body { padding: 9px 11px 10px; border-top: 1px solid var(--line); background: var(--panel-2); }
.show-card-sub {
  display: block; font-size: 11.5px; color: var(--dim); margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.show-card-actions {
  position: absolute; left: 8px; right: 8px; top: 8px; z-index: 3;
  display: flex; gap: 6px; opacity: 0; transition: opacity .12s;
}
.show-card:hover .show-card-actions { opacity: 1; }
.show-card-actions .btn { flex: 1; backdrop-filter: blur(6px); background: rgba(20, 24, 34, .88); }

/* ------------------------------------------------ admin: account rows */

.account-row {
  display: flex; align-items: center; gap: 16px;
  padding: 11px 13px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--panel-2); margin-bottom: 8px;
}
.account-meta { flex: 1; min-width: 0; }
.account-name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.account-meta .line { color: var(--dim); font-size: 12px; margin-top: 2px; }
.account-actions { display: flex; gap: 7px; }

.inline-edit {
  background: none; border: 1px dashed transparent; border-radius: 6px;
  padding: 2px 6px; margin-left: -6px; color: inherit; text-align: left;
  transition: border-color .12s, background .12s;
}
.inline-edit:hover { border-color: var(--line); background: var(--panel-3); }
.inline-edit.strong { font-size: 14.5px; font-weight: 620; letter-spacing: -.01em; }
.inline-edit.host { font-size: 12.5px; color: var(--muted); }
.inline-edit.host.empty { color: var(--dim); font-style: italic; }
.inline-input { width: 220px; padding: 4px 8px; font-size: 13.5px; }

.topbar .host-name { color: var(--dim); font-size: 12.5px; }
.topbar .host-name::before { content: "with "; }

/* -------------------------------------------------- editor: the words

   The daily job. Five boxes in a column, big enough to read, with the colour
   of each line sitting right next to the line it changes. */

.word-field { margin-bottom: 12px; }
.word-field.active .word-label { color: var(--text); }
.word-label {
  display: flex; align-items: center; gap: 7px; margin-bottom: 5px;
  font-size: 11px; font-weight: 650; letter-spacing: .08em;
  text-transform: uppercase; color: var(--dim); transition: color .12s;
}

/* The headline is the line of the day, not the fifth item in a list of five. */
.word-field.is-headline {
  position: relative; margin-bottom: 18px; padding-left: 11px;
}
.word-field.is-headline::before {
  content: ''; position: absolute; left: 0; top: 2px; bottom: 2px; width: 3px;
  border-radius: 3px; background: linear-gradient(180deg, var(--accent-2), var(--accent));
}
.word-field.is-headline .word-label { font-size: 11.5px; color: #ff8d8d; }
.word-field.is-headline .word-input {
  font-size: 15px; font-weight: 600; padding: 11px 12px; letter-spacing: .01em;
}

/* The four topics read as one set, under their own quiet heading. */
.word-group {
  display: flex; align-items: center; gap: 10px; margin: 2px 0 10px;
  font-size: 10.5px; font-weight: 650; letter-spacing: .1em;
  text-transform: uppercase; color: var(--dim);
}
.word-group::after {
  content: ''; flex: 1; height: 1px; background: var(--line);
}
.word-chip {
  display: inline-grid; place-items: center; width: 17px; height: 17px;
  border-radius: 5px; background: var(--panel-2); border: 1px solid var(--line);
  font-size: 10px; letter-spacing: 0; color: var(--muted);
}
.word-field.active .word-chip { border-color: var(--focus); color: var(--text); }

/* A button that will not hold another word says so, briefly. */
.word-field.is-full .word-input {
  border-color: var(--warn); box-shadow: 0 0 0 3px rgba(240,180,60,.16);
  animation: word-full .22s ease;
}
.word-field.is-full .word-label::after {
  content: 'full'; margin-left: auto; color: var(--warn);
  font-size: 10px; letter-spacing: .06em;
}
@keyframes word-full {
  25% { transform: translateX(-2px); } 75% { transform: translateX(2px); }
}
@media (prefers-reduced-motion: reduce) { .word-field.is-full .word-input { animation: none; } }
.word-row { display: flex; gap: 7px; align-items: stretch; }
.word-input { flex: 1; font-size: 13.5px; padding: 9px 11px; }
.word-field.active .word-input { border-color: var(--focus); box-shadow: 0 0 0 3px rgba(76,141,255,.17); }
.word-input:disabled { opacity: .5; cursor: not-allowed; }
.word-swatch {
  flex: 0 0 34px; width: 34px; border-radius: var(--r);
  border: 1px solid var(--line); padding: 0;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12);
  transition: transform .1s, border-color .12s;
}
.word-swatch:hover { transform: scale(1.06); border-color: #3d4a63; }
.word-locked { display: block; margin-top: 5px; font-size: 11px; color: var(--warn); }

/* Wording longer than the button holds: flagged, never touched. */
.word-note { margin: 5px 0 0; font-size: 11px; line-height: 1.35; color: var(--warn); }
.word-field:not(.is-oversize) .word-note { display: none; }
.word-field.is-oversize .word-input { border-color: rgba(240,192,76,.55); }
.word-foot { margin-top: 16px; margin-bottom: 0; }

.color-popover {
  position: fixed; z-index: 70; width: 286px; padding: 14px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow);
}

.toggle-row { display: flex; gap: 8px; margin-bottom: 4px; }
.toggle-row .btn { flex: 1; }

/* Add page offers two kinds; the menu keeps that to one extra click. */
.add-menu {
  position: fixed; z-index: 75; width: 272px; padding: 6px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow);
}
.add-menu-item {
  display: block; width: 100%; text-align: left; padding: 10px 12px;
  background: none; border: none; border-radius: 9px; transition: background .1s;
}
.add-menu-item:hover { background: var(--panel-2); }
.add-menu-item strong { display: block; font-size: 13.5px; font-weight: 600; }
.add-menu-item span { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }

/* A sponsor page reads differently in the strip so it is obvious at a glance. */
.page-thumb.sponsor { border-color: #6b5a12; }
.page-thumb .kind {
  position: absolute; left: 4px; top: 4px; background: rgba(240,192,76,.9);
  color: #1b1600; font-size: 9px; font-weight: 800; letter-spacing: .05em;
  padding: 1px 5px; border-radius: 4px;
}

/* Renaming a show, right on its card in the grid. */
.show-card-name {
  display: block; width: 100%; text-align: left; padding: 0;
  background: none; border: none; color: var(--text);
  font-size: 13px; font-weight: 620; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.show-card-name:hover { color: var(--focus); }
.show-card-name::after { content: " ✎"; opacity: 0; font-size: 11px; transition: opacity .12s; }
.show-card:hover .show-card-name::after { opacity: .55; }

.card-rename {
  position: fixed; z-index: 80; width: 248px; padding: 14px;
  background: var(--panel); border: 1px solid var(--line);
  box-shadow: var(--shadow);
  display: flex; flex-direction: column; gap: 8px;
  border-radius: var(--r-lg);
}
.card-rename label { display: block; font-size: 10.5px; font-weight: 650;
  letter-spacing: .07em; text-transform: uppercase; color: var(--dim); }
.card-rename .input { margin-top: 3px; padding: 6px 9px; font-size: 12.5px; }
.card-rename-note { margin: 0; font-size: 10.5px; color: var(--dim); line-height: 1.4; }
.card-rename-row { display: flex; gap: 7px; margin-top: 2px; }
.card-rename-row .btn { flex: 1; }

.inline-edit.login { font-size: 12px; color: var(--dim); font-family: ui-monospace, monospace; }

/* Arrange in the top bar: it acts on the canvas, so it sits next to it. */
.arrange-bar { display: flex; align-items: center; gap: 8px; }
.arrange-bar[hidden] { display: none; }
.arrange-what {
  font-size: 12px; font-weight: 620; color: var(--muted);
  white-space: nowrap; max-width: 130px; overflow: hidden; text-overflow: ellipsis;
}
.arrange-buttons { display: flex; gap: 4px; }
.arrange-buttons .btn { padding: 6px 12px; font-size: 12px; border-radius: 999px; }


/* Dragging a page to move it in the running order. */
.page-thumb { cursor: grab; }
.page-thumb.dragging { opacity: .4; cursor: grabbing; }
.page-strip { scroll-behavior: smooth; }

#picture-panel:not(:empty) {
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line);
}



/* Uploads: a contact sheet, each picture at its own shape, the way Canva does
   it. Clicking one places it - the rest hides behind the corner menu. */
.upload-grid { column-count: 2; column-gap: 8px; }
.upload-tile {
  position: relative; break-inside: avoid; margin-bottom: 8px;
  border-radius: 9px; overflow: hidden;
}
.upload-image {
  display: block; width: 100%; padding: 0; border: none; background: none;
  border-radius: 9px; overflow: hidden; cursor: pointer;
}
.upload-image img {
  width: 100%; display: block; border-radius: 9px;
  background-color: #0e121a;
  background-image:
    linear-gradient(45deg, #1a2029 25%, transparent 25%),
    linear-gradient(-45deg, #1a2029 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #1a2029 75%),
    linear-gradient(-45deg, transparent 75%, #1a2029 75%);
  background-size: 10px 10px; background-position: 0 0, 0 5px, 5px -5px, -5px 0;
  transition: outline-color .12s;
  outline: 2px solid transparent; outline-offset: -2px;
}
.upload-image:hover img { outline-color: var(--focus); }
.upload-tile.is-overlay .upload-image img { outline-color: var(--accent); }
.upload-badge {
  position: absolute; left: 5px; top: 5px; pointer-events: none;
  background: var(--accent); color: #fff; font-size: 9px; font-weight: 700;
  letter-spacing: .05em; padding: 2px 5px; border-radius: 4px;
}


/* Overlay row: one compact line at the top of Uploads, because the overlay is
   set once and then forgotten about. */
.overlay-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px; margin-bottom: 12px;
  border: 1px solid var(--line); border-radius: 11px; background: var(--panel-2);
}
.overlay-row-thumb {
  flex: 0 0 56px; height: 32px; border-radius: 6px; overflow: hidden;
  background-color: #0e121a;
  background-image:
    linear-gradient(45deg, #1a2029 25%, transparent 25%),
    linear-gradient(-45deg, #1a2029 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #1a2029 75%),
    linear-gradient(-45deg, transparent 75%, #1a2029 75%);
  background-size: 8px 8px; background-position: 0 0, 0 4px, 4px -4px, -4px 0;
}
.overlay-row-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.overlay-row-label { flex: 1; font-size: 11.5px; color: var(--muted); line-height: 1.3; }

.dropzone-note { display: block; margin-top: 6px; font-size: 11.5px; color: var(--dim); }

/* Tile actions: visible on hover, no menus. */
.tile-action {
  position: absolute; width: 26px; height: 26px; padding: 0;
  border: none; border-radius: 7px; line-height: 1; font-size: 13px;
  background: rgba(8, 10, 16, .85); color: #fff;
  opacity: 0; transition: opacity .12s, background .12s;
}
.upload-tile:hover .tile-action { opacity: 1; }
.tile-overlay { left: 5px; top: 5px; }
.tile-overlay:hover { background: var(--accent); }
.tile-bin { right: 5px; top: 5px; }
.tile-bin:hover { background: var(--accent); }
.upload-tile.is-overlay .tile-overlay { opacity: 1; background: var(--accent); }


/* ------------------------------------------------------------- position */

/* Halves of the Position panel: move this one / see them all. */
.subtabs {
  display: flex; gap: 4px; padding: 4px;
  margin: 0 0 14px;
  background: var(--sunken, rgba(255,255,255,.04));
  border-radius: 9px;
}
.subtab {
  flex: 1; padding: 7px 10px;
  border: 0; border-radius: 6px;
  background: transparent; color: var(--muted);
  font: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer;
}
.subtab:hover { color: var(--text); }
.subtab.active { background: var(--raised, rgba(255,255,255,.09)); color: var(--text); }

.subpanel { display: none; }
.subpanel.active { display: block; }

.panel-label {
  margin: 0 0 9px;
  font-size: 11px; font-weight: 650; letter-spacing: .06em;
  text-transform: uppercase; color: var(--dim);
}

/* Four ways to move a layer, as a square of equal choices rather than a row of
   words - the shape of the icon says which is which faster than reading does. */
.order-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px;
  margin-bottom: 12px;
}
.order-btn {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 12px 6px;
  border: 1px solid var(--line); border-radius: 9px;
  background: var(--raised, rgba(255,255,255,.04)); color: var(--text);
  font: inherit; font-size: 11.5px; font-weight: 550;
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
.order-btn:hover { background: rgba(255,255,255,.09); border-color: var(--accent); }
.order-btn:active { transform: translateY(1px); }
.order-btn svg {
  width: 20px; height: 20px;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.order-btn svg .ghost { opacity: .35; }

/* A control that exists but cannot apply here - the overlay's ordering, say.
   Visible so nothing looks missing, plainly unavailable so nothing looks broken. */
.order-btn:disabled,
.btn:disabled {
  opacity: .4;
  cursor: not-allowed;
}
.order-btn:disabled:hover {
  background: var(--raised, rgba(255,255,255,.04));
  border-color: var(--line);
}

/* ==========================================================================
   Shine.

   A pass of depth and motion over the chrome. Everything here is restrained
   on purpose: the graphic is the thing people are looking at, and this is a
   tool someone opens at 7am to do one job. Contrast and hit sizes are left
   alone - nothing below makes anything harder to see or harder to click.
   ========================================================================== */

/* Buttons lift very slightly and pick up a top highlight, the way a real
   surface catches light. */
.btn {
  position: relative;
  background-image: linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,0));
  box-shadow: 0 1px 0 rgba(255,255,255,.05) inset, 0 1px 2px rgba(0,0,0,.25);
  transition: transform .12s ease, box-shadow .16s ease,
              background-color .16s ease, border-color .16s ease;
}
.btn:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 1px 0 rgba(255,255,255,.07) inset, 0 6px 16px rgba(0,0,0,.35);
}
.btn:active:not(:disabled) { transform: translateY(0); box-shadow: 0 1px 2px rgba(0,0,0,.3) inset; }
.btn:disabled { transform: none; box-shadow: none; background-image: none; }

/* The one button everyone presses at the end of the day. */
.btn-primary {
  background-image: linear-gradient(180deg, var(--accent-2), var(--accent));
  border-color: rgba(255,255,255,.14);
  box-shadow: 0 1px 0 rgba(255,255,255,.22) inset, 0 4px 14px rgba(226,59,59,.32);
}
.btn-primary:hover:not(:disabled) {
  box-shadow: 0 1px 0 rgba(255,255,255,.28) inset, 0 8px 24px rgba(226,59,59,.45);
}

/* Download is its own progress bar: a bright fill sweeps across the button
   with a live percentage, so it never reads as frozen, then a green tick. */
#btn-export { overflow: hidden; isolation: isolate; font-variant-numeric: tabular-nums; }
#btn-export.is-working, #btn-export.is-done { min-width: 168px; }
#btn-export.is-working { cursor: progress; }
#btn-export.is-working::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  width: var(--progress, 0%);
  background: linear-gradient(90deg, rgba(255,255,255,.16), rgba(255,255,255,.34));
  transition: width .3s ease;
}
#btn-export.is-working::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,.28) 50%, transparent 70%);
  background-size: 220% 100%;
  animation: export-sheen 1.1s linear infinite;
}
@keyframes export-sheen { from { background-position: 120% 0; } to { background-position: -120% 0; } }
#btn-export.is-done {
  background-image: linear-gradient(180deg, #4fd99a, var(--good));
  border-color: rgba(255,255,255,.18);
  box-shadow: 0 1px 0 rgba(255,255,255,.25) inset, 0 4px 14px rgba(62,201,138,.35);
}
@media (prefers-reduced-motion: reduce) { #btn-export.is-working::after { animation: none; } }

/* After a multi-page download: one button per page, in case the browser let
   only the first through. */
.dl-help {
  position: fixed; right: 16px; top: 72px;   /* JS drops it just under the toolbar */
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  max-width: min(92vw, 760px); padding: 10px 12px;
  background: var(--panel-2, #14181f); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: 0 12px 34px rgba(0,0,0,.45);
  z-index: 95; animation: dl-help-in .18s ease-out;
}
@keyframes dl-help-in { from { opacity: 0; transform: translateY(-8px); } }
.dl-help-text { font-size: 13px; color: var(--muted, #9aa4b2); }
.dl-help .btn.saved { border-color: var(--good); color: var(--good); }
.dl-help-close {
  background: none; border: 0; color: var(--muted, #9aa4b2);
  font-size: 18px; line-height: 1; cursor: pointer; padding: 2px 4px;
}
.dl-help-close:hover { color: #fff; }
@media (prefers-reduced-motion: reduce) { .dl-help { animation: none; } }

/* Keyboard focus stays obvious - this is the opposite of subtle on purpose. */
.btn:focus-visible, .input:focus-visible, .tab:focus-visible,
.subtab:focus-visible, .order-btn:focus-visible, .layer:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* The top bar reads as a surface with the room lit from above. */
.topbar {
  background-image: linear-gradient(180deg, rgba(255,255,255,.035), rgba(255,255,255,0));
  box-shadow: 0 1px 0 rgba(255,255,255,.05) inset, 0 8px 24px -18px rgba(0,0,0,.9);
}

/* The active tab's underline slides rather than jumps. */
.tab { transition: color .16s ease; }
.tab::after { transition: transform .2s cubic-bezier(.4,0,.2,1), opacity .2s ease; }

/* Typing boxes settle into focus instead of snapping. */
.input {
  transition: border-color .16s ease, box-shadow .16s ease, background-color .16s ease;
}
.input:focus {
  box-shadow: 0 0 0 3px rgba(76,141,255,.18);
}

/* Page thumbnails: a little depth, and the current one clearly lifted. */
.page-thumb {
  transition: transform .14s ease, box-shadow .16s ease, border-color .16s ease;
  box-shadow: 0 2px 6px rgba(0,0,0,.35);
}
.page-thumb:hover { transform: translateY(-2px); box-shadow: 0 10px 22px rgba(0,0,0,.45); }
.page-thumb.current { box-shadow: 0 0 0 2px var(--accent), 0 10px 24px rgba(226,59,59,.25); }

/* Upload tiles come up to meet the cursor. */
.upload-tile { transition: transform .14s ease, box-shadow .16s ease; }
.upload-tile:hover { transform: translateY(-2px); box-shadow: 0 12px 26px rgba(0,0,0,.45); }

/* Layer rows shift a hair on hover, so the list feels alive under the mouse. */
.layer { transition: background .12s ease, border-color .12s ease, transform .12s ease; }
.layer:hover { transform: translateX(2px); }

/* The saved/saving indicator fades between states instead of flicking. */
.save-state { transition: color .25s ease, opacity .25s ease; }

/* Toast arrives from below rather than appearing. */
#toast {
  transition: transform .22s cubic-bezier(.2,.8,.2,1), opacity .22s ease;
  box-shadow: 0 16px 40px rgba(0,0,0,.55);
}

/* Respect a machine set to reduce motion - some people turn that on for a
   reason, and none of the above is load-bearing. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
  .btn:hover, .page-thumb:hover, .upload-tile:hover, .layer:hover { transform: none; }
}

/* ==========================================================================
   Phones and tablets.

   The desktop shape is a sidebar beside a 1920-wide canvas, which cannot work
   on a phone. So it stacks: the graphic on top where it is being looked at,
   the typing underneath where the thumbs are. The canvas resizes itself from
   whatever room it is given, so nothing here has to tell it how big to be.
   ========================================================================== */

@media (max-width: 900px) {
  /* One column, and the artwork first - it is the thing being judged. */
  .workspace {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }

  /* Grid and flex children refuse by default to shrink below the natural width
     of what is inside them, so one wide row of page thumbnails was holding the
     whole column open at 760px on a 375px screen and pushing the canvas off the
     side. This lets them shrink; the things that need to scroll already do. */
  .workspace, .side, .stage-area, .stage-scroll, .pages, .page-strip,
  .tabs, .tab-panels, .tab-panel, .arrange-bar { min-width: 0; }
  .stage-area { order: 1; min-height: 0; }
  .side {
    order: 2;
    border-right: 0;
    border-top: 1px solid var(--line);
    min-height: 0;
  }

  /* Enough of the screen to judge the graphic, not so much that the words are
     pushed off the bottom. */
  .stage-area { max-height: 54vh; }
  .stage-scroll { padding: 10px; }

  /* The top bar earns its height back: the logo shrinks, the host name goes
     (it is on the graphic anyway), and what is left may wrap. */
  .app > .topbar { flex: 0 0 auto; }
  .topbar {
    flex-wrap: wrap;
    height: auto;
    padding: 8px 10px;
    gap: 8px;
  }
  .topbar .logo { height: 20px; }
  .topbar .host-name { display: none; }
  .topbar .show-name { font-size: 13px; max-width: 42vw; overflow: hidden;
                       text-overflow: ellipsis; white-space: nowrap; }
  .topbar .divider { display: none; }

  /* Whatever is selected gets its own full-width row rather than squeezing
     the sign-out button off the screen. */
  .arrange-bar {
    order: 10;
    flex-basis: 100%;
    padding-top: 8px;
    border-top: 1px solid var(--line-soft);
    overflow-x: auto;
  }
}

@media (max-width: 640px) {
  /* Fingers, not a mouse: every control gets a proper target. Apple's floor is
     44px and it is the right number - below it people miss and blame
     themselves. */
  .btn { min-height: 42px; padding: 10px 14px; }
  .btn-sm { min-height: 42px; }
  .tab { padding: 14px 12px; }
  .subtab { padding: 12px 10px; }

  /* 16px or iOS zooms the whole page in the moment a box is tapped, and the
     person is then stranded at 150% with no obvious way back. */
  .input, .word-input { font-size: 16px; }
  /* The headline keeps its extra weight without dropping under that floor. */
  .word-field.is-headline .word-input { font-size: 17px; }

  /* Two per row rather than four - a 25%-wide upload tile on a phone is a
     thumbnail of a thumbnail. */
  .upload-grid { column-count: 2; }

  /* Page thumbnails big enough to tell apart and to hit. */
  .page-thumb { min-width: 92px; }
  .pages { padding: 8px 10px; }

  /* The ordering square stays a square, just roomier. */
  .order-btn { padding: 14px 6px; }

  /* Give the words more of the screen: on a phone the graphic only has to be
     recognisable, and the typing is the whole job. */
  .stage-area { max-height: 46vh; }
}

/* A finger is not a mouse pointer: no hover, and far less precision. Lifting
   effects are pointless on touch and the outlines want to be thicker. */
@media (pointer: coarse) {
  .btn:hover:not(:disabled),
  .page-thumb:hover,
  .upload-tile:hover,
  .layer:hover { transform: none; box-shadow: none; }
  .tile-overlay, .tile-bin { opacity: 1; }   /* no hover to reveal them */
}

@media (max-width: 900px) {
  /* The page row, stacked. Side by side, two big buttons were squeezing the
     thumbnails down to a sliver - and the thumbnails are how you find the page
     you want. Strip first, full width; the buttons get their own line. */
  .pages { flex-direction: column; align-items: stretch; gap: 8px; }
  .page-strip { width: 100%; }
  .page-actions { display: flex; gap: 8px; }
  .page-actions .btn { flex: 1; }        /* two equal, thumb-sized targets */

  /* "All changes saved" was running off the edge. It matters, so it keeps its
     place - it just gets its own line rather than fighting for one. */
  .topbar .save-state { font-size: 12px; margin-left: auto; }
}

@media (max-width: 420px) {
  /* At the narrow end, the two header buttons share a line evenly rather than
     letting Download push Sign out off the screen. */
  .topbar #btn-export { flex: 1; }
  .topbar .save-state { flex-basis: 100%; text-align: right; margin: 0; }
}

/* ==========================================================================
   The admin screen on a phone.

   This was built for a wide desktop - a header row of controls, a packed grid
   of show cards, side-by-side forms - and none of it survived a 375px screen.
   The worst of it was invisible rather than ugly: the buttons on each card only
   appeared on hover, and a phone has no hover, so renaming a show or opening
   its pages was simply impossible.
   ========================================================================== */

@media (max-width: 820px) {
  /* The header. Sign out was sitting at x=437 on a 375px screen - off the side
     of the world - and dragging the whole page sideways with it. */
  .admin-top {
    flex-wrap: wrap;
    height: auto;
    padding: 10px 14px;
    gap: 8px 10px;
  }
  .admin-top .logo { height: 20px; }
  .admin-top .divider { display: none; }
  .admin-top .admin-title { font-size: 13px; }
  .admin-top .spacer { display: none; }

  /* The two views are the main navigation, so they get a full row to
     themselves and split it evenly - two big, obvious targets. */
  .admin-nav { order: 10; flex-basis: 100%; margin-left: 0; }
  .admin-nav .admin-tab { flex: 1; }

  .admin-wrap { padding: 18px 14px 56px; }

  /* Title, search and sort stack instead of competing for one line. */
  .gallery-head { flex-direction: column; align-items: stretch; gap: 10px; }
  .gallery-head .spacer { display: none; }
  .gallery-head .input,
  .gallery-head #search { width: 100%; }
  .gallery-head #sort { width: 100% !important; }
  .gallery-head h1 { font-size: 19px; }

  /* One card per row. A 228px card on a 375px screen would be two cramped
     columns; one full-width card shows the actual graphic, which is the whole
     point of this screen. */
  .gallery-grid { grid-template-columns: 1fr; gap: 12px; }

  /* Forms go single file. Two columns on a phone means two unusable columns. */
  .form-grid { grid-template-columns: 1fr; }

  /* An account row was a wide flex line; stacked, each show reads as a block
     with its buttons underneath. */
  .account-row { flex-wrap: wrap; gap: 10px; }
  .account-meta { flex-basis: 100%; }
  .account-row .btn { flex: 1; }

  /* The preview takes the whole screen - there is no room for a dialog that
     floats politely in the middle of a phone. */
  .modal-backdrop { padding: 0; }
  .modal { max-width: 100%; width: 100%; height: 100%; max-height: 100%;
           border-radius: 0; border: 0; }
  .modal-foot { flex-wrap: wrap; }
  .modal-foot .btn { flex: 1; }
  .preview-grid { grid-template-columns: 1fr; }
}

/* No hover on a touch screen, so anything that only appears on hover is
   invisible and unreachable. These are the controls for renaming a show,
   opening its pages and downloading them - not decoration. */
@media (pointer: coarse) {
  .show-card-actions { opacity: 1; }
  .show-card-name::after { opacity: .55; }
  .show-card:hover { transform: none; box-shadow: none; }
}

/* Every typing box, at a size iOS will not zoom for.
   Anything under 16px makes Safari zoom the page in the instant the box is
   tapped, and there is no obvious way back out - the person is just stranded
   at 150% wondering what they broke. These selectors are deliberately as
   specific as the rules they override: .card-rename .input is two classes, so
   a bare .input rule loses to it. */
@media (max-width: 820px) {
  .input,
  .word-input,
  .inline-input,
  .card-rename .input,
  input, select, textarea { font-size: 16px; }

  /* 16px type needs more room than the desktop popover allowed, so it grows to
     fit the screen it is actually on. */
  .card-rename {
    width: min(340px, calc(100vw - 24px));
    padding: 16px;
  }
  .card-rename .input { padding: 9px 11px; }
  .card-rename label { font-size: 11px; }
  .card-rename-note { font-size: 11.5px; }
}

/* The admin strip on a custom segment: unmissable, and only for Fan Arch. */
.segment-admin {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 16px; background: linear-gradient(90deg, rgba(76,141,255,.16), rgba(76,141,255,.04));
  border-bottom: 1px solid rgba(76,141,255,.35); font-size: 13px; color: var(--text);
}
.segment-admin[hidden] { display: none; }
/* .btn sets its own display, which beats the browser default for [hidden]. */
.segment-admin .btn[hidden] { display: none; }
.segment-admin .spacer { flex: 1; }
.segment-admin-tag {
  font-size: 10px; font-weight: 700; letter-spacing: .1em;
  padding: 3px 7px; border-radius: 5px;
  background: rgba(76,141,255,.25); color: #cfe0ff;
}
