/* ===========================================================================
   Littera Scripta review UI — design system
   Palette is drawn from the journal's own print identity (the DOCX
   template's banner green, #044E2B) so the web tool and the document it
   produces feel like the same product, not two unrelated things.
   =========================================================================== */

:root {
  --ink: #16181d;
  --ink-soft: #5b616e;
  --ink-faint: #8a90a0;
  --border: #e2e4ea;
  --border-soft: #edeff3;
  --bg: #ffffff;
  --bg-soft: #f7f8fa;
  --bg-raised: #ffffff;
  --surface-sunken: #f2f3f6;

  --accent: #0b4a2e;
  --accent-strong: #063a23;
  --accent-soft: #e7f1ec;
  --accent-contrast: #ffffff;

  --gold: #b6862c;
  --gold-soft: #faf3e3;

  --ok: #157a4a;
  --ok-bg: #e6f6ee;
  --warn: #92650a;
  --warn-bg: #fdf1dc;
  --err: #b3261e;
  --err-bg: #fcebea;

  --radius-sm: 7px;
  --radius: 11px;
  --radius-lg: 16px;
  --radius-pill: 999px;

  --shadow-xs: 0 1px 2px rgba(20, 22, 30, 0.05);
  --shadow-sm: 0 2px 8px rgba(20, 22, 30, 0.06), 0 1px 2px rgba(20, 22, 30, 0.05);
  --shadow-md: 0 8px 24px rgba(20, 22, 30, 0.09), 0 2px 6px rgba(20, 22, 30, 0.05);
  --shadow-lg: 0 16px 40px rgba(20, 22, 30, 0.14), 0 4px 12px rgba(20, 22, 30, 0.06);
  --shadow-focus: 0 0 0 3.5px rgba(11, 74, 46, 0.16);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --font-serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Inter", Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace;

  /* Page background, site-wide (body, below). A tileable fractal-noise SVG
     — barely-there paper grain (max alpha 0.05), the same trick fine
     stationery/print sites use for a tactile, non-flat surface instead of
     a dead-flat fill. Theme-invariant on purpose: it's monochrome noise at
     very low alpha, so it reads correctly blended over either a light or
     dark backdrop without needing its own light/dark variant. */
  --bg-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.05 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");

  /* Elsevier/ScienceDirect-style tokens (see
     Elsevier_Style_Public_Site_Redesign_SPECIFICATION.md) — public journal
     website pages only (journal/articles/article/issues/issue/board/
     policies/policy/search/publisher). Colors sampled pixel-by-pixel from
     real ScienceDirect screenshots, not guessed. New names, so defining
     them globally can't affect --accent or any existing rule. */
  --els-blue: #0272b1;
  --els-blue-hover: #025a8c;
  --els-cyan: #16a3ce;
  --els-orange: #eb6500;
  --els-ink: #1f1f1f;
  --els-ink-soft: #5b5b5b;
  --els-bg: #ffffff;
  --els-bg-soft: #f5f5f5;
  --els-border: #d9d9d9;
  --els-green: #2e7d32;

  /* SpringerLink-style tokens — index.html (the platform homepage) only.
     No live/archived reference could be fetched this pass (the real site
     loops through a cookie-auth redirect our fetch tool can't follow, and
     Wayback Machine access is blocked), so these are Springer's real,
     long-stable, well-known brand teal rather than a pixel-sampled value
     like the Elsevier tokens above. New names, so defining them globally
     can't affect any existing rule. */
  --spr-teal: #00857c;
  --spr-teal-dark: #00655e;
  --spr-teal-light: #e6f4f3;
  --spr-ink: #1a1a1a;
  --spr-ink-soft: #5c5c5c;
  --spr-bg: #ffffff;
  --spr-bg-soft: #f7f9f9;
  --spr-border: #dfe6e5;

  /* Editorial Dashboard UI Redesign tokens — the 10 core editorial/staff
     pages only. No reference image was actually attached to that spec
     (text-only, despite saying "supplied image"); these follow its very
     detailed written color/spacing rules instead. Reuses --ok/--warn/--err
     for Published/Queue/Critical status (already exist); adds the two
     colors the spec names that this app didn't have yet (Review/Process
     blue, Revision purple) plus a soft pink for the Draft stat card. */
  --ed-info: #0b5fae;
  --ed-info-bg: #e8f1fb;
  --ed-purple: #6d3aa8;
  --ed-purple-bg: #f1e9f8;
  --ed-pink: #b3265e;
  --ed-pink-bg: #fbe9f0;
  --ed-sidebar-width: 240px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #e9ebf0;
    --ink-soft: #a6acbb;
    --ink-faint: #767c8c;
    --border: #2b2e38;
    --border-soft: #23262f;
    --bg: #101216;
    --bg-soft: #16181e;
    --bg-raised: #1a1d24;
    --surface-sunken: #0c0e12;

    --accent: #4fbf8b;
    --accent-strong: #6fd4a4;
    --accent-soft: #12291f;
    --accent-contrast: #05130d;

    --gold: #e0b158;
    --gold-soft: #2b2314;

    --ok: #5fd39a;
    --ok-bg: #10291d;
    --warn: #f0b429;
    --warn-bg: #332705;
    --err: #f28b82;
    --err-bg: #331311;

    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.35);
    --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 10px 28px rgba(0, 0, 0, 0.5);
    --shadow-lg: 0 20px 48px rgba(0, 0, 0, 0.55);
    --shadow-focus: 0 0 0 3.5px rgba(79, 191, 139, 0.28);

    --els-blue: #5bbde8;
    --els-blue-hover: #8ad2ee;
    --els-cyan: #1c7793;
    --els-orange: #ff8a3d;
    --els-ink: #eceef2;
    --els-ink-soft: #a8adb8;
    --els-bg: #14161b;
    --els-bg-soft: #1c1f26;
    --els-border: #2b2e38;
    --els-green: #5fbf6a;

    --spr-teal: #3dbdb3;
    --spr-teal-dark: #6bd4ca;
    --spr-teal-light: #123330;
    --spr-ink: #eceef2;
    --spr-ink-soft: #a8adb8;
    --spr-bg: #14161b;
    --spr-bg-soft: #1c1f26;
    --spr-border: #2b2e38;

    --ed-info: #6cb2f2;
    --ed-info-bg: #142a3f;
    --ed-purple: #c19bee;
    --ed-purple-bg: #2a1f3c;
    --ed-pink: #ef8ab3;
    --ed-pink-bg: #3a1928;
  }
}

/* Explicit overrides (e.g. an in-app theme toggle stamping data-theme on
   <html>) always win over the OS-level prefers-color-scheme media query,
   in either direction. */
:root[data-theme="dark"] {
  --ink: #e9ebf0; --ink-soft: #a6acbb; --ink-faint: #767c8c;
  --border: #2b2e38; --border-soft: #23262f; --bg: #101216; --bg-soft: #16181e; --bg-raised: #1a1d24; --surface-sunken: #0c0e12;
  --accent: #4fbf8b; --accent-strong: #6fd4a4; --accent-soft: #12291f; --accent-contrast: #05130d;
  --gold: #e0b158; --gold-soft: #2b2314;
  --ok: #5fd39a; --ok-bg: #10291d; --warn: #f0b429; --warn-bg: #332705; --err: #f28b82; --err-bg: #331311;
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.35); --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 10px 28px rgba(0, 0, 0, 0.5); --shadow-lg: 0 20px 48px rgba(0, 0, 0, 0.55);
  --shadow-focus: 0 0 0 3.5px rgba(79, 191, 139, 0.28);
  --els-blue: #5bbde8; --els-blue-hover: #8ad2ee; --els-cyan: #1c7793; --els-orange: #ff8a3d;
  --els-ink: #eceef2; --els-ink-soft: #a8adb8; --els-bg: #14161b; --els-bg-soft: #1c1f26; --els-border: #2b2e38; --els-green: #5fbf6a;
  --spr-teal: #3dbdb3; --spr-teal-dark: #6bd4ca; --spr-teal-light: #123330;
  --spr-ink: #eceef2; --spr-ink-soft: #a8adb8; --spr-bg: #14161b; --spr-bg-soft: #1c1f26; --spr-border: #2b2e38;
  --ed-info: #6cb2f2; --ed-info-bg: #142a3f; --ed-purple: #c19bee; --ed-purple-bg: #2a1f3c; --ed-pink: #ef8ab3; --ed-pink-bg: #3a1928;
  color-scheme: dark;
}
:root[data-theme="light"] {
  --ink: #16181d; --ink-soft: #5b616e; --ink-faint: #8a90a0;
  --border: #e2e4ea; --border-soft: #edeff3; --bg: #ffffff; --bg-soft: #f7f8fa; --bg-raised: #ffffff; --surface-sunken: #f2f3f6;
  --accent: #0b4a2e; --accent-strong: #063a23; --accent-soft: #e7f1ec; --accent-contrast: #ffffff;
  --gold: #b6862c; --gold-soft: #faf3e3;
  --ok: #157a4a; --ok-bg: #e6f6ee; --warn: #92650a; --warn-bg: #fdf1dc; --err: #b3261e; --err-bg: #fcebea;
  --shadow-xs: 0 1px 2px rgba(20, 22, 30, 0.05); --shadow-sm: 0 2px 8px rgba(20, 22, 30, 0.06), 0 1px 2px rgba(20, 22, 30, 0.05);
  --shadow-md: 0 8px 24px rgba(20, 22, 30, 0.09), 0 2px 6px rgba(20, 22, 30, 0.05); --shadow-lg: 0 16px 40px rgba(20, 22, 30, 0.14), 0 4px 12px rgba(20, 22, 30, 0.06);
  --shadow-focus: 0 0 0 3.5px rgba(11, 74, 46, 0.16);
  --els-blue: #0272b1; --els-blue-hover: #025a8c; --els-cyan: #16a3ce; --els-orange: #eb6500;
  --els-ink: #1f1f1f; --els-ink-soft: #5b5b5b; --els-bg: #ffffff; --els-bg-soft: #f5f5f5; --els-border: #d9d9d9; --els-green: #2e7d32;
  --spr-teal: #00857c; --spr-teal-dark: #00655e; --spr-teal-light: #e6f4f3;
  --spr-ink: #1a1a1a; --spr-ink-soft: #5c5c5c; --spr-bg: #ffffff; --spr-bg-soft: #f7f9f9; --spr-border: #dfe6e5;
  --ed-info: #0b5fae; --ed-info-bg: #e8f1fb; --ed-purple: #6d3aa8; --ed-purple-bg: #f1e9f8; --ed-pink: #b3265e; --ed-pink-bg: #fbe9f0;
  color-scheme: light;
}

* { box-sizing: border-box; }
*:focus-visible {
  outline: 2.5px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

html {
  color-scheme: light dark;
  /* The sticky app header (~76px tall) sits on top of the page at all
     times — without this, scrolling/focusing an element near the top of
     the viewport (e.g. Playwright's or a keyboard user's scrollIntoView)
     can land it *underneath* the header, where it visually overlaps and
     silently intercepts clicks/taps. */
  scroll-padding-top: 84px;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 15px;
  color: var(--ink);
  /* Dual-tone gradient mesh (the journal's own green + its gold accent,
     both already theme-correct via the tokens above) plus the paper-grain
     texture on top — a deliberate, asymmetric wash instead of one flat
     color or a single centered blob, applied site-wide (every page shares
     this body, editorial dashboard included — .ed-app/.ed-main paint no
     background of their own). background-attachment: fixed keeps it
     reading as ambient light on the surface rather than something printed
     on the page that would swim/tile oddly as you scroll a long page. */
  background-color: var(--bg);
  background-image:
    var(--bg-grain),
    radial-gradient(1150px 680px at 108% -14%, color-mix(in srgb, var(--accent) 20%, transparent), transparent 62%),
    radial-gradient(950px 640px at -12% 106%, color-mix(in srgb, var(--gold) 16%, transparent), transparent 64%);
  background-repeat: repeat, no-repeat, no-repeat;
  background-position: 0 0, 0 0, 0 0;
  background-attachment: fixed, fixed, fixed;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* .els-board-home's full-bleed technique (100vw + negative margins) can
     overhang by a scrollbar's width — this keeps that from ever producing
     a horizontal scrollbar of its own. */
  overflow-x: hidden;
}

main { max-width: 1080px; margin: 0 auto; padding: 1.75rem 1.5rem 5rem; }
.app-main--hidden { display: none; }

h1, h2, h3 { font-family: var(--font-serif); font-weight: 600; letter-spacing: -0.01em; color: var(--ink); }
h1 { font-size: 1.4rem; margin: 0; }
h2 { font-size: 1.32rem; margin: 0 0 0.4rem; display: flex; align-items: center; gap: 0.55rem; }
h3 { font-size: 1.02rem; margin: 1.5rem 0 0.6rem; font-weight: 600; }
/* Portal pages' own page title (My Submissions, Editor Queue, etc.) reads
   as a direct child of <main> — give it more presence than a bare h1
   otherwise gets, without touching the many places h1 is reused as a
   compact in-header/in-card label (format.html's masthead, auth cards). */
.pub-main > h1 { font-size: 1.75rem; margin-bottom: 0.3rem; }
.auth-card h1 { font-size: 1.6rem; }

code {
  font-family: var(--font-mono);
  font-size: 0.85em;
  background: var(--surface-sunken);
  border: 1px solid var(--border-soft);
  border-radius: 5px;
  padding: 0.1em 0.4em;
}

a { color: var(--accent); }

/* -- App header -------------------------------------------------------- */

.app-header {
  border-bottom: 1px solid var(--border-soft);
  background: color-mix(in srgb, var(--bg-soft) 92%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  position: sticky;
  top: 0;
  z-index: 30;
}
.app-header__main {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.85rem 1.75rem;
}
.app-header__title { display: flex; align-items: center; gap: 0.75rem; }
.app-header__actions { display: flex; align-items: center; gap: 0.9rem; }
.app-header__mark {
  display: grid;
  place-items: center;
  width: 2.15rem;
  height: 2.15rem;
  border-radius: 8px;
  background: linear-gradient(155deg, var(--accent) 0%, var(--accent-strong) 100%);
  color: var(--accent-contrast);
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 0.95rem;
  box-shadow: var(--shadow-sm);
  flex: none;
}
/* Real uploaded logo image (Editable Journal Logo and Branding spec §17:
   "do not force every asset into identical dimensions... avoid destructive
   stretching") — overrides .app-header__mark's fixed square/gradient
   treatment (built for the 2-letter text-mark fallback) with a natural-
   aspect-ratio image capped to roughly the same visual height. */
.app-header__mark--logo {
  background: none;
  box-shadow: none;
  width: auto;
  height: 3.2rem;
  max-width: 13rem;
  object-fit: contain;
  border-radius: 0;
}
/* Both combined selectors (not just ".app-header__mark") so this beats
   .els-masthead/.spr-header's own ".app-header__mark" background rule below
   on specificity — a real bug this fixes: those rules were previously
   winning (equal specificity + later in file, or no override existing at
   all for .spr-header), so an uploaded transparent-PNG logo showed a
   translucent white box through its transparent areas instead of the bare
   masthead color underneath. */
.els-masthead .app-header__mark.app-header__mark--logo,
.spr-header .app-header__mark.app-header__mark--logo,
.author-topbar--branded .app-header__mark.app-header__mark--logo { background: none; box-shadow: none; }
.author-topbar--branded .app-header__mark { background: rgba(255, 255, 255, 0.18); color: #ffffff; }
.app-header h1 { line-height: 1.15; }
.app-header__subtitle { display: block; font-size: 0.78rem; color: var(--ink-soft); margin-top: 0.1rem; }

.job-status { display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; }
.job-status--hidden { display: none; }
.job-status__label { color: var(--ink-soft); }
.job-status__stage { color: var(--ink-soft); }
#job-status-id { background: var(--bg); border: 1px solid var(--border); border-radius: 4px; padding: 0.1rem 0.4rem; font-size: 0.75rem; }

/* Production's Upload step: auto-loaded manuscript info when the accepted
   article came from the Submission System (the only source this app has —
   see ArticleService.production_source's docstring). */
.manuscript-source {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  background: var(--bg-soft);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  padding: 0.9rem 1.1rem;
  margin: 0.9rem 0;
}
.manuscript-source--hidden { display: none; }
.manuscript-source__row { display: flex; align-items: center; gap: 0.6rem; font-size: 0.88rem; }
.manuscript-source__label { color: var(--ink-soft); min-width: 5.5rem; }
.manuscript-source__actions { display: flex; gap: 0.6rem; margin-top: 0.2rem; }
.manuscript-source-missing--hidden { display: none; }

.badge {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.65rem;
  border-radius: var(--radius-pill);
  font-size: 0.74rem;
  font-weight: 650;
  letter-spacing: 0.01em;
  background: var(--accent-soft);
  color: var(--accent);
}
.badge--warn { background: var(--warn-bg); color: var(--warn); }
.badge--ok { background: var(--ok-bg); color: var(--ok); }
.badge--err { background: var(--err-bg); color: var(--err); }
.badge--muted { background: var(--bg-soft); color: var(--ink-faint); }

/* -- Step navigation ----------------------------------------------------- */

.steps {
  display: flex;
  gap: 0.15rem;
  padding: 0 1.5rem;
  border-bottom: 1px solid var(--border-soft);
  overflow-x: auto;
  background: var(--bg-soft);
}
.steps--hidden { display: none; }
.steps__tab {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  border: none;
  background: none;
  font: inherit;
  font-size: 0.88rem;
  color: var(--ink-faint);
  padding: 0.9rem 0.95rem;
  border-bottom: 2.5px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.18s var(--ease);
  position: relative;
}
.steps__num {
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  font-size: 0.72rem;
  font-weight: 700;
  background: var(--surface-sunken);
  color: var(--ink-faint);
  border: 1px solid var(--border);
  transition: all 0.2s var(--ease);
  flex: none;
}
.steps__label { transition: color 0.18s var(--ease); }
.steps__tab:not(:disabled):hover { color: var(--ink-soft); }
.steps__tab:disabled { cursor: not-allowed; }
.steps__tab:disabled .steps__num { opacity: 0.55; }
.steps__tab:not(:disabled):not([aria-current="step"]) .steps__num {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
  /* the digit is a raw text node (not its own span), so it can't be hidden
     with a sibling selector — collapse it with font-size:0 and give the
     checkmark pseudo-element its own font-size back, otherwise both the "✓"
     and the original number stack as separate grid items in this
     place-items:center circle and the digit pokes out underneath it. */
  font-size: 0;
}
.steps__tab:not(:disabled):not([aria-current="step"]) .steps__num::before {
  content: "✓";
  font-size: 0.72rem;
}
.steps__tab[aria-current="step"] {
  color: var(--ink);
  border-bottom-color: var(--accent);
  font-weight: 650;
}
.steps__tab[aria-current="step"] .steps__num {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
  box-shadow: 0 0 0 4px var(--accent-soft);
}

/* -- Step sections as cards ---------------------------------------------- */

.step {
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 1.9rem 2rem 2.1rem;
  margin-top: 1.5rem;
  animation: step-in 0.32s var(--ease);
  scroll-margin-top: 84px;
}
@keyframes step-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

.step__hint { color: var(--ink-soft); font-size: 0.9rem; margin-top: 0; margin-bottom: 1.4rem; max-width: 68ch; }

/* -- Forms ----------------------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: 0.35rem; margin-bottom: 1rem; flex: 1; min-width: 160px; }
.field--hidden { display: none; }
.field label { font-size: 0.8rem; font-weight: 600; color: var(--ink-soft); letter-spacing: 0.005em; }
.field-row { display: flex; gap: 1rem; flex-wrap: wrap; border: none; padding: 0; margin: 0; }
.field-row legend { font-size: 0.82rem; color: var(--ink-soft); padding: 0 0 0.4rem; width: 100%; }

input[type="text"], input[type="number"], input[type="date"], input[type="email"], input[type="file"], select, textarea {
  font: inherit;
  font-size: 0.92rem;
  padding: 0.6rem 0.75rem;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--ink);
  transition: border-color 0.16s var(--ease), box-shadow 0.16s var(--ease);
}
input:hover, select:hover, textarea:hover { border-color: var(--ink-faint); }
input:focus, select:focus, textarea:focus {
  border-color: var(--accent);
  box-shadow: var(--shadow-focus);
}
/* The box-shadow ring above is already a fully visible focus indicator —
   skip the generic outline here so focused fields don't show two rings. */
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; }
input[type="file"] { padding: 0.5rem 0.6rem; cursor: pointer; }
textarea { resize: vertical; min-height: 3.5rem; }

/* -- Buttons ---------------------------------------------------------------- */

.btn {
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  border-radius: var(--radius-sm);
  border: 1.5px solid var(--border);
  background: var(--bg);
  color: var(--ink);
  padding: 0.62rem 1.15rem;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  transition: transform 0.15s var(--ease), box-shadow 0.15s var(--ease), background 0.15s var(--ease), border-color 0.15s var(--ease);
}
.btn:not(:disabled):hover { transform: translateY(-1px); box-shadow: var(--shadow-sm); border-color: var(--ink-faint); }
.btn:not(:disabled):active { transform: translateY(0); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn--disabled { opacity: 0.5; cursor: not-allowed; pointer-events: none; }
.btn--primary {
  background: linear-gradient(155deg, var(--accent) 0%, var(--accent-strong) 130%);
  border-color: var(--accent);
  color: var(--accent-contrast);
  box-shadow: var(--shadow-xs);
}
.btn--primary:not(:disabled):hover {
  background: linear-gradient(155deg, var(--accent-strong) 0%, var(--accent) 130%);
  border-color: var(--accent-strong);
  box-shadow: var(--shadow-md);
}
.btn--primary:disabled { background: var(--ink-faint); border-color: var(--ink-faint); }
.btn--secondary { background: var(--bg-soft); }
.btn--secondary:not(:disabled):hover { background: var(--surface-sunken); }
.btn--danger { background: var(--err); border-color: var(--err); color: #fff; }
.btn--danger:not(:disabled):hover { filter: brightness(0.9); box-shadow: var(--shadow-md); }
.btn--sm { padding: 0.35rem 0.75rem; font-size: 0.78rem; flex: none; }

/* ORCID's own brand green (#A6CE39) — https://orcid.org (brand guidelines:
   the iD icon always keeps this color, never re-colored to match a host
   site's palette). Used only for this one button/badge, not folded into
   the shared accent tokens. */
.btn--orcid {
  width: 100%;
  justify-content: center;
  background: #fff;
  border-color: #A6CE39;
  color: #333;
}
.btn--orcid:not(:disabled):hover { background: #f3f8e7; border-color: #A6CE39; }
.orcid-icon { width: 1.1em; height: 1.1em; flex: none; }
.auth-divider { display: flex; align-items: center; gap: 0.75rem; margin: 1.1rem 0; color: var(--ink-faint); font-size: 0.8rem; }
.auth-divider::before, .auth-divider::after { content: ""; flex: 1; height: 1px; background: var(--border); }

.orcid-status { display: flex; align-items: center; gap: 0.5rem; font-size: 0.92rem; }
.orcid-status__badge { color: #A6CE39; font-weight: 600; display: inline-flex; align-items: center; gap: 0.3em; }

/* -- Toast / startup error ---------------------------------------------- */

.toast {
  position: sticky;
  top: 0.5rem;
  z-index: 10;
  padding: 0.7rem 1.1rem;
  border-radius: var(--radius);
  margin-bottom: 1.1rem;
  font-size: 0.9rem;
  font-weight: 550;
  box-shadow: var(--shadow-sm);
  animation: toast-in 0.25s var(--ease);
}
@keyframes toast-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.toast--hidden { display: none; }
.toast--error { background: var(--err-bg); color: var(--err); }
.toast--success { background: var(--ok-bg); color: var(--ok); }
.toast--info { background: var(--accent-soft); color: var(--accent); }

.startup-error {
  position: sticky;
  top: 0;
  z-index: 40;
  padding: 0.9rem 1.5rem;
  background: var(--err-bg);
  color: var(--err);
  font-size: 0.9rem;
  border-bottom: 1px solid var(--err);
}
.startup-error--hidden { display: none; }
.startup-error code {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.1rem 0.4rem;
  color: var(--ink);
}

.banner { padding: 0.75rem 1.1rem; border-radius: var(--radius); margin-bottom: 1.1rem; font-size: 0.88rem; font-weight: 550; box-shadow: var(--shadow-xs); }
.banner--hidden { display: none; }
.banner--warn { background: var(--warn-bg); color: var(--warn); }
.banner--ok { background: var(--ok-bg); color: var(--ok); }

/* -- Structure review ------------------------------------------------------ */

.structure-toolbar { display: flex; align-items: center; gap: 0.85rem; margin-bottom: 1rem; flex-wrap: wrap; }
.dirty-count { color: var(--ink-soft); font-size: 0.85rem; }

.table-wrap { overflow-x: auto; border: 1px solid var(--border-soft); border-radius: var(--radius); box-shadow: var(--shadow-xs); }
table { border-collapse: collapse; width: 100%; font-size: 0.87rem; }
th, td { text-align: left; padding: 0.65rem 0.75rem; border-bottom: 1px solid var(--border-soft); vertical-align: top; }
th { background: var(--bg-soft); position: sticky; top: 0; font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-soft); font-weight: 650; }
tbody tr { transition: background 0.15s var(--ease); }
tbody tr:hover { background: var(--bg-soft); }
tbody tr:last-child td { border-bottom: none; }
.col-reviewed { width: 4rem; text-align: center; }
.col-level { width: 6rem; }
.col-section { width: 9rem; }
.col-confidence { width: 6rem; }

tr.row--low { background: var(--err-bg); }
tr.row--low:hover { background: color-mix(in srgb, var(--err-bg) 75%, var(--bg-soft)); }
tr.row--medium { background: var(--warn-bg); }
tr.row--medium:hover { background: color-mix(in srgb, var(--warn-bg) 75%, var(--bg-soft)); }
tr.row--confirmed { opacity: 0.68; }
tr.row--flash { animation: flash 1.4s ease-out; }
@keyframes flash { from { background: var(--accent-soft); } to { background: transparent; } }

.block-text { display: block; width: 100%; font-family: inherit; font-size: 0.85rem; border-radius: var(--radius-sm); }
.confidence-pill { font-weight: 700; font-variant-numeric: tabular-nums; }
.confidence-pill--low { color: var(--err); }
.confidence-pill--medium { color: var(--warn); }
.confidence-pill--high { color: var(--ok); }

/* -- Author cards ------------------------------------------------------------ */

.author-card {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 1rem 1.1rem;
  margin-bottom: 0.9rem;
  background: var(--bg-soft);
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.author-card:hover { border-color: var(--border); box-shadow: var(--shadow-xs); }
.author-card__row { display: flex; gap: 0.75rem; flex-wrap: wrap; }
.author-card__footer { display: flex; justify-content: space-between; align-items: center; margin-top: 0.65rem; }
.checkbox-field { display: flex; align-items: center; gap: 0.45rem; font-size: 0.85rem; color: var(--ink-soft); }
.checkbox-field input { accent-color: var(--accent); width: 1.05rem; height: 1.05rem; }

/* -- Recent manuscripts / resume ------------------------------------------- */

.recent-jobs--hidden { display: none; }
.recent-jobs-empty-hint--hidden { display: none; }
.upload-start-block--hidden { display: none; }
.recent-jobs__list { display: flex; flex-direction: column; gap: 0.65rem; }
.recent-job-row {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg-soft);
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.recent-job-row:hover { border-color: var(--border); box-shadow: var(--shadow-xs); }
.recent-job-row__main { flex: 1; min-width: 0; }
.recent-job-row__filename {
  font-weight: 650;
  font-size: 0.92rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.recent-job-row__meta { display: flex; align-items: center; gap: 0.55rem; margin-top: 0.3rem; font-size: 0.78rem; color: var(--ink-soft); }
.recent-job-row__actions { display: flex; align-items: center; gap: 0.9rem; flex: none; }

/* -- Step footer: Back/Next wizard navigation ------------------------------ */

.step-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.75rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--border-soft);
}
.step-footer .btn--primary { margin-left: auto; }

.format-actions { display: flex; gap: 0.75rem; margin-bottom: 1.1rem; flex-wrap: wrap; }
.result-box { padding: 0.85rem 1.1rem; border-radius: var(--radius); background: var(--bg-soft); border: 1px solid var(--border-soft); margin-bottom: 1.1rem; font-size: 0.88rem; }
.result-box--hidden { display: none; }

.validation-summary--hidden { display: none; }
.validation-counts { display: flex; gap: 0.5rem; margin-bottom: 0.85rem; }

.download-list { list-style: none; padding: 0; display: flex; gap: 0.75rem; flex-wrap: wrap; margin: 0 0 0.5rem; }

.publish-panel { padding: 0.85rem 1.1rem; border-radius: var(--radius); background: var(--bg-soft); border: 1px solid var(--border-soft); margin-bottom: 1.1rem; display: flex; flex-direction: column; align-items: flex-start; gap: 0.6rem; }
.publish-panel__actions { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; }

.link-btn {
  background: none;
  border: none;
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  font-size: 0.85rem;
  padding: 0;
  transition: border-color 0.15s var(--ease);
}
.link-btn:hover { border-bottom-color: var(--accent); }
.link-btn--danger { color: var(--err); border-bottom-color: color-mix(in srgb, var(--err) 40%, transparent); }
.link-btn--danger:hover { border-bottom-color: var(--err); }

/* -- Step 1: mode choice --------------------------------------------------- */

.mode-choice { border: none; padding: 0; margin: 0 0 1.4rem; }
.mode-choice legend { font-size: 0.8rem; font-weight: 600; color: var(--ink-soft); padding: 0 0 0.55rem; }
.mode-option {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.7rem;
  row-gap: 0.15rem;
  align-items: start;
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  padding: 0.8rem 1rem;
  margin-bottom: 0.6rem;
  cursor: pointer;
  transition: border-color 0.15s var(--ease), background 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.mode-option:hover { border-color: var(--ink-faint); }
.mode-option:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 10%, transparent); }
.mode-option input { grid-row: 1 / 3; margin-top: 0.2rem; accent-color: var(--accent); width: 1.05rem; height: 1.05rem; }
.mode-option__title { font-weight: 650; }
.mode-option__hint { grid-column: 2; font-size: 0.82rem; color: var(--ink-soft); }

/* -- Structure review: advanced-column toggle + grouping ------------------ */

.structure-toolbar__advanced { margin-left: auto; font-size: 0.85rem; }
.adv-col { display: none; }
table.show-advanced .adv-col { display: table-cell; }
tr.group-header td {
  background: var(--surface-sunken);
  font-weight: 700;
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent);
  border-bottom: 1px solid var(--border);
  border-top: 1px solid var(--border);
}

/* -- Metadata: required marks, field errors, chips, previews -------------- */

.required-mark { color: var(--err); }
.optional-mark { color: var(--ink-faint); font-size: 0.82rem; font-weight: 400; }
.field-error { display: block; font-size: 0.78rem; color: var(--err); min-height: 1em; }
.field.field--invalid input { border-color: var(--err); }
.field.field--invalid input:focus { box-shadow: 0 0 0 3.5px color-mix(in srgb, var(--err) 16%, transparent); }
.field.field--required-missing input { border-color: var(--warn); }

.chip-input {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  padding: 0.5rem;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  transition: border-color 0.16s var(--ease), box-shadow 0.16s var(--ease);
}
.chip-input:focus-within { border-color: var(--accent); box-shadow: var(--shadow-focus); }
.chip-input input {
  border: none;
  outline: none;
  background: transparent;
  font: inherit;
  font-size: 0.9rem;
  flex: 1;
  min-width: 8rem;
  padding: 0.2rem;
  color: var(--ink);
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: var(--radius-pill);
  padding: 0.2rem 0.5rem 0.2rem 0.7rem;
  font-size: 0.82rem;
  font-weight: 600;
}
.chip--invalid { background: var(--err-bg); color: var(--err); }
.chip__remove { background: none; border: none; color: inherit; cursor: pointer; font: inherit; line-height: 1; padding: 0.15rem; opacity: 0.7; border-radius: 50%; transition: opacity 0.15s var(--ease), background 0.15s var(--ease); }
.chip__remove:hover { opacity: 1; background: rgba(0, 0, 0, 0.08); }

.preview-box { margin-top: 1.1rem; padding: 0.8rem 1rem; border: 1px dashed var(--border); border-radius: var(--radius); background: var(--bg-soft); }
.preview-box__label { font-size: 0.76rem; font-weight: 650; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-faint); margin-bottom: 0.3rem; }
.preview-box__content { font-size: 0.94rem; font-family: var(--font-serif); }

.affiliation-row { display: flex; align-items: center; flex-wrap: wrap; gap: 0.6rem; margin-bottom: 0.55rem; }
.affiliation-row__id { font-weight: 700; color: var(--accent); width: 1.5rem; text-align: right; }
.affiliation-row input { flex: 1; min-width: 9rem; }

/* A flex item that's a plain <div> wrapping a width:100% child has no
   intrinsic min-content of its own to fall back on — flexbox's default
   min-width:auto then collapses it far below its siblings (which do have
   a real intrinsic width) instead of giving it a fair, equal share. */
.institution-field { position: relative; flex: 1; min-width: 9rem; }
.institution-field input { width: 100%; box-sizing: border-box; }
.institution-suggestions {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 20;
  background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); margin-top: 0.3rem; max-height: 14rem; overflow-y: auto;
}
.institution-suggestion {
  display: block; width: 100%; text-align: left; padding: 0.5rem 0.75rem; border: none; background: none;
  font: inherit; font-size: 0.85rem; cursor: pointer; color: inherit; transition: background 0.12s var(--ease);
}
.institution-suggestion:hover, .institution-suggestion:focus { background: var(--bg-soft); }

.affiliation-picker { display: flex; flex-wrap: wrap; gap: 0.7rem; }
.affiliation-picker label { display: flex; align-items: center; gap: 0.35rem; font-size: 0.85rem; }
.affiliation-picker input { accent-color: var(--accent); }

/* -- Step 4: status banner, preview panel, grouped validation -------------- */

.manuscript-status {
  padding: 0.85rem 1.15rem;
  border-radius: var(--radius);
  margin-bottom: 1.1rem;
  font-weight: 650;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  box-shadow: var(--shadow-xs);
}
.manuscript-status--hidden { display: none; }
.manuscript-status--ready { background: var(--ok-bg); color: var(--ok); }
.manuscript-status--ready::before { content: "✓"; }
.manuscript-status--warnings { background: var(--warn-bg); color: var(--warn); }
.manuscript-status--warnings::before { content: "!"; }
.manuscript-status--blocked { background: var(--err-bg); color: var(--err); }
.manuscript-status--blocked::before { content: "✕"; }

.preview-panel { margin: 1.5rem 0; }
.preview-panel--hidden { display: none; }
.preview-panel__tabs { display: flex; gap: 0.4rem; margin-bottom: 0.85rem; flex-wrap: wrap; }
.preview-panel__tabs button {
  font: inherit; font-size: 0.83rem; font-weight: 600; padding: 0.4rem 0.85rem; border-radius: var(--radius-pill);
  border: 1.5px solid var(--border); background: var(--bg); color: var(--ink-soft); cursor: pointer;
  transition: all 0.15s var(--ease);
}
.preview-panel__tabs button:hover { border-color: var(--ink-faint); color: var(--ink); }
.preview-panel__tabs button[aria-current="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-contrast); box-shadow: var(--shadow-xs); }
.preview-panel__image {
  max-width: 100%;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  background: var(--bg-soft);
}

.preview-panel__pager { display: flex; align-items: center; gap: 0.7rem; margin-bottom: 0.9rem; }
.preview-panel__indicator { font-size: 0.85rem; color: var(--ink-soft); min-width: 7rem; text-align: center; font-variant-numeric: tabular-nums; }
.preview-panel__jump { width: 4.2rem; padding: 0.35rem 0.5rem; border: 1.5px solid var(--border); border-radius: var(--radius-sm); font: inherit; text-align: center; }

.validation-group {
  margin-bottom: 1rem;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 0.9rem 1.1rem 0.3rem;
  background: var(--bg-soft);
}
.validation-group__title { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.045em; color: var(--accent); margin-bottom: 0.5rem; }
.issue-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.85rem; padding: 0.65rem 0; border-bottom: 1px solid var(--border-soft); font-size: 0.88rem; }
.issue-row:last-child { border-bottom: none; }
.issue-row__main { flex: 1; }
.issue-row__code { color: var(--ink-soft); font-size: 0.78rem; margin-top: 0.15rem; }

/* -- Step 5: download page -------------------------------------------------- */

.download-summary { margin-bottom: 1.2rem; font-size: 0.98rem; font-weight: 550; }
.download-summary__warning { color: var(--warn); font-size: 0.88rem; margin-top: 0.4rem; font-weight: 500; }
.download-summary__blocked { color: var(--err); font-size: 0.88rem; margin-top: 0.4rem; font-weight: 500; }
.advanced-downloads { margin-top: 1.4rem; }
.advanced-downloads summary { cursor: pointer; color: var(--ink-soft); font-size: 0.88rem; margin-bottom: 0.85rem; font-weight: 600; }
.advanced-downloads summary:hover { color: var(--ink); }

/* -- Scrollbar polish (webkit) ---------------------------------------------- */

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 999px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: var(--ink-faint); }

/* -- Responsive -------------------------------------------------------------- */

@media (max-width: 640px) {
  main { padding: 1rem 0.85rem 4rem; }
  .step { padding: 1.35rem 1.25rem 1.6rem; border-radius: var(--radius); }
  .app-header__main { padding: 0.85rem 1rem; }
  .steps { padding: 0 0.75rem; }
  .steps__label { display: none; }
  .steps__tab { padding: 0.75rem 0.5rem; }

  /* A sticky header on a small screen is a well-known source of "why
     won't this tap" bugs — mobile browsers frequently auto-scroll a
     focused field (or a programmatic scrollIntoView) flush to the top of
     the viewport without accounting for scroll-padding-top, landing it
     directly under the header, where it silently swallows the tap. Screen
     space is scarcer here too, so let these scroll away normally instead
     of staying pinned (the toast and table header have the same risk). */
  .app-header, .toast, th { position: static; }

  /* table's width:100% (set for the desktop layout) forces every column
     to shrink to fit a narrow viewport instead of letting .table-wrap's
     overflow-x:auto do its job — the source-content textarea in
     particular becomes an unreadable single-character-wide column. A
     minimum table width restores the intended "scroll sideways" pattern
     for a wide data table on a small screen. */
  #structure-table { width: max-content; min-width: 100%; }
  .col-text { min-width: 12rem; }
  .col-detected { min-width: 8rem; }

  /* three actions (Resume / View log / Delete) plus a filename no longer
     fit on one line at this width — same fixed-width-sibling squeeze as
     .affiliation-row, so wrap instead of overflowing. */
  .recent-job-row { flex-wrap: wrap; }
  .recent-job-row__actions { flex-wrap: wrap; gap: 0.6rem 0.9rem; }
}

/* -- LinkedIn Post step ------------------------------------------------------ */

.hidden-field { display: none !important; }

.linkedin-connection {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg-soft);
  margin-bottom: 0.9rem;
}
.linkedin-connection__status { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.linkedin-connection__label { font-weight: 650; font-size: 0.88rem; }
.linkedin-connection__account { font-size: 0.85rem; color: var(--ink-soft); }
.linkedin-connection__actions { display: flex; gap: 0.5rem; }

.linkedin-counts { display: flex; gap: 1.1rem; font-size: 0.8rem; color: var(--ink-soft); margin-top: 0.4rem; }
.linkedin-counts__bad { color: var(--err); font-weight: 600; }

.linkedin-media-preview { width: 100%; max-width: 380px; border-radius: var(--radius); border: 1px solid var(--border-soft); margin-top: 0.75rem; display: block; cursor: zoom-in; }

/* width: min(100%, 62vh) keeps the (square) card comfortably on-screen even
   on a short viewport, not just a narrow one — plain max-width alone only
   bounds the horizontal dimension. */
.linkedin-card-fullsize { display: block; width: min(100%, 62vh); height: auto; margin: 0 auto; border-radius: var(--radius); border: 1px solid var(--border-soft); }

.modal__panel.li-card-modal__panel { max-width: 50rem; }
.li-card-modal__body { display: flex; gap: 1.2rem; align-items: flex-start; }
.li-card-modal__body > .linkedin-card-fullsize { flex: 0 1 auto; min-width: 0; }
.li-card-modal__side { flex: 0 0 200px; display: flex; flex-direction: column; gap: 0.5rem; }
@media (max-width: 640px) {
  .li-card-modal__body { flex-direction: column; }
  .li-card-modal__side { flex-basis: auto; width: 100%; }
}

.li-card-theme { margin-top: 0.6rem; }
.li-card-theme__label { display: block; font-size: 0.8rem; color: var(--ink-soft); margin-bottom: 0.45rem; }
.li-card-theme__palettes { display: flex; gap: 0.45rem; flex-wrap: wrap; }
.li-palette-chip {
  display: flex; width: 68px; height: 34px; padding: 0; overflow: hidden; cursor: pointer;
  border-radius: 8px; border: 2px solid var(--border);
}
.li-palette-chip > span { flex: 1; }
.li-palette-chip[aria-pressed="true"] { border-color: var(--ink); box-shadow: 0 0 0 2px var(--bg-soft); }
.li-card-theme__row { display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; margin-top: 0.6rem; }
.li-card-theme__custom { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.8rem; color: var(--ink-soft); }
.li-card-theme__custom input[type="color"] { width: 30px; height: 26px; padding: 0; border: 1px solid var(--border); border-radius: 6px; background: none; cursor: pointer; }

.linkedin-preview {
  white-space: pre-wrap;
  font-family: var(--font-serif);
  font-size: 0.94rem;
  line-height: 1.5;
}

.modal {
  position: fixed;
  inset: 0;
  background: rgba(10, 15, 12, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
  padding: 1rem;
}
.modal--hidden { display: none; }
.modal__panel {
  background: var(--bg-raised);
  border-radius: var(--radius-lg, var(--radius));
  box-shadow: var(--shadow-md);
  padding: 1.5rem 1.75rem;
  max-width: 32rem;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
}
.modal__panel--wide { max-width: 42rem; }
.modal__actions { display: flex; justify-content: flex-end; gap: 0.6rem; margin-top: 1.2rem; }

/* Side drawer — same overlay-click-to-close convention as .modal, but the
   panel itself slides in from the right edge and takes the full viewport
   height, for reading a long piece of content (e.g. journal.html's "View
   full aims & scope") without leaving the page behind it. */
.side-drawer {
  position: fixed;
  inset: 0;
  background: rgba(10, 15, 12, 0.45);
  z-index: 50;
  display: flex;
  justify-content: flex-end;
}
.side-drawer__panel {
  background: var(--bg-raised);
  box-shadow: var(--shadow-md);
  width: min(34rem, 100%);
  height: 100%;
  overflow-y: auto;
  padding: 1.75rem;
  animation: side-drawer-in 0.22s var(--ease);
}
@keyframes side-drawer-in {
  from { transform: translateX(100%); }
  to { transform: translateX(0); }
}
.side-drawer__heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.side-drawer__heading h2 { margin: 0; }
.side-drawer__close {
  background: none;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-pill);
  width: 2.1rem;
  height: 2.1rem;
  flex: none;
  display: inline-grid;
  place-items: center;
  cursor: pointer;
  color: var(--ink-soft);
  font-size: 1.05rem;
  line-height: 1;
}
.side-drawer__close:hover, .side-drawer__close:focus-visible { border-color: var(--accent); color: var(--accent); }

/* Dynamic Journal Issue Cover Generator's "Preview cover" popup — a real
   full-size view, not the small inline thumbnail this replaced. Sized off
   viewport height (the cover is a tall 1600x2200 portrait) rather than a
   fixed max-width like other modals, so it reads as a genuine large
   preview on any screen. */
/* max-height was 80vh, leaving too little of the modal's own 90vh cap for
   the header row + Previous/Next row below the image — on most real
   screens that pushed the nav buttons below the fold, only reachable by
   scrolling inside the popup, which isn't obvious and read as "the
   buttons aren't there at all". 62vh leaves real, reliable room for both
   surrounding rows on top of the image itself. */
.cover-preview-lightbox__panel { max-width: min(90vw, 40rem); padding: 1.25rem; display: flex; flex-direction: column; }
.cover-preview-lightbox__img { display: block; width: 100%; height: auto; max-height: 62vh; object-fit: contain; border-radius: var(--radius-sm); margin-top: 0.75rem; flex: none; }

/* ===========================================================================
   Public Journal Website (spec §7-8, §28-29) — reuses every token above,
   no new custom properties. Free dark-mode support via the existing
   prefers-color-scheme / [data-theme] overrides.
   =========================================================================== */

.pub-header {
  border-bottom: 1px solid var(--border-soft);
  background: color-mix(in srgb, var(--bg-soft) 92%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  position: sticky;
  top: 0;
  z-index: 30;
}
/* Slim breadcrumb bar above the journal brand/logo — establishes "you are
   here" (Home › Journal › Section › Page) before the journal's own
   masthead and nav take over. renderBreadcrumb() (public.js) replaces this
   element's children with a .pub-breadcrumb <ol> on every page that calls
   it; a page that doesn't (none currently) keeps the plain static "VSTE"
   link that ships in the HTML. */
.pub-topbar {
  padding: 0.55rem 1.75rem;
  border-bottom: 1px solid var(--border-soft);
  background: var(--bg-soft);
}
/* > a, not a plain descendant selector — scopes this to the static
   fallback "VSTE" link only (a direct child of .pub-topbar in the HTML).
   The breadcrumb's own links sit one level deeper (.pub-breadcrumb li a)
   and get their own un-uppercased treatment below; without this scoping
   they inherited this rule's uppercase/letter-spacing too, since it has
   equal specificity and the breadcrumb rules never reset those two
   properties explicitly. */
.pub-topbar > a { color: var(--ink-faint); text-decoration: none; font-size: 0.78rem; font-weight: 600; letter-spacing: 0.03em; text-transform: uppercase; }
.pub-topbar > a:hover { color: var(--accent); }

.pub-breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; list-style: none; padding: 0; margin: 0; font-size: 0.8rem; min-width: 0; }
.pub-breadcrumb li { display: flex; align-items: center; gap: 0.4rem; min-width: 0; }
.pub-breadcrumb a {
  color: var(--ink-faint);
  text-decoration: none;
  font-weight: 600;
  transition: color 0.15s ease;
}
.pub-breadcrumb a:hover { color: var(--accent); }
/* vertical-align (not a flex wrapper) so the icon+text combo on the "Home"
   link stays a normal inline flow — needed for text-overflow: ellipsis to
   work at all below, which requires a block/inline-block container, not a
   flex one (a flex container silently ignores text-overflow entirely). */
.pub-breadcrumb svg { vertical-align: -0.1em; margin-right: 0.3rem; opacity: 0.75; transition: opacity 0.15s ease; }
.pub-breadcrumb a:hover svg { opacity: 1; }
.pub-breadcrumb span[aria-current="page"] {
  display: inline-block;
  vertical-align: bottom;
  color: var(--ink);
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 26rem;
}
.pub-breadcrumb__sep { color: var(--ink-faint); opacity: 0.55; flex: none; font-size: 0.85em; }
.pub-header__main {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.85rem 1.75rem;
}
.pub-header__brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--ink);
  text-decoration: none;
}
.pub-header__actions { display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap; }

.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 2.05rem;
  height: 2.05rem;
  flex: none;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-soft);
  background: var(--bg-raised);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.12s ease, transform 0.12s ease;
}
.theme-toggle:hover { border-color: var(--ink-faint); transform: translateY(-1px); }

/* ---------------------------------------------------------------------------
   Elsevier/ScienceDirect-style journal masthead + secondary nav bar. Colors
   sampled from a real ScienceDirect journal page (see the redesign spec).
   .els-masthead is a wrapper class shared by all 11 public reader-facing
   pages, article.html/article-preview.html included (those two also keep
   their own compact in-content .els-article-masthead further down the
   page) — not used by the author/reviewer portal and hub pages
   (dashboard.html, submit.html, reviewer-workspace.html, account.html,
   index.html), which still keep the plain global .pub-header__main.
   --------------------------------------------------------------------------- */
.els-masthead {
  background:
    radial-gradient(900px 300px at 15% -60%, rgba(255, 255, 255, 0.16), transparent),
    linear-gradient(120deg, var(--els-cyan) 0%, color-mix(in srgb, var(--els-cyan) 82%, #063a52) 100%);
  padding-bottom: 1.3rem;
}
/* Header + logo size bump, ~20% larger (real user request) — scoped to
   .els-masthead (the 11 reader-facing public pages) specifically, not the
   shared base .pub-header__main/.app-header__mark rules above, since those
   are also used by the author/reviewer portal and hub pages (dashboard.html,
   submit.html, reviewer-workspace.html, account.html, index.html), which
   this request didn't ask to change. */
.els-masthead .pub-header__main { padding-top: 1.05rem; padding-bottom: 0.5rem; }
.els-masthead .pub-header__brand { color: #ffffff; font-family: var(--font-sans); font-weight: 600; font-size: 1.55rem; }
.els-masthead .app-header__mark { background: rgba(255, 255, 255, 0.18); color: #ffffff; width: 3.2rem; height: 3.2rem; }
.els-masthead .app-header__mark--logo { height: 5rem; max-width: 18rem; }
.els-masthead .theme-toggle { background: rgba(255, 255, 255, 0.14); border-color: rgba(255, 255, 255, 0.3); color: #ffffff; }
.els-masthead .theme-toggle:hover { border-color: #ffffff; }
.els-masthead__meta { margin: 0; padding: 0 1.75rem; color: rgba(255, 255, 255, 0.92); font-size: 0.92rem; }
.els-masthead__meta:empty { display: none; }

.pub-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* row-gap separate from column-gap — a bare `gap: 1.6rem` shorthand sets
     both, which is fine on desktop's single row but on a narrow viewport
     where these links wrap onto 2-3 lines, that same 1.6rem became a huge
     vertical gap between rows too. */
  column-gap: 1.6rem;
  row-gap: 0.1rem;
  padding: 0 1.75rem;
  background: var(--els-bg);
  border-bottom: 1px solid var(--els-border);
}
/* Auth-aware nav area sits at the right edge of the menu bar itself
   (Authentication-Aware Navigation Bar spec §1's own mockup: "Home |
   Articles | ... | For Authors    User Name ▾"), not up in the brand row
   above it — margin-left: auto pushes just this one flex item right while
   the nav links stay grouped left, independent of wrapping/gap. */
.pub-nav .pub-auth-area { margin-left: auto; padding: 0.5rem 0; }
/* :not(.btn) — this rule is meant for plain text nav links (Home,
   Articles, ...) but .pub-auth-area's Login/Register/account-menu buttons
   are also <a> tags living inside .pub-nav, and this selector's higher
   specificity (class+tag) was silently beating .btn--primary's own
   color/padding, leaving Register's text nearly unreadable against its
   own background. */
.pub-nav a:not(.btn) {
  display: inline-block;
  color: var(--els-ink-soft);
  text-decoration: none;
  font-size: 0.92rem;
  font-weight: 500;
  padding: 0.75rem 0.1rem;
  border-bottom: 2.5px solid transparent;
}
.pub-nav a:not(.btn):hover { color: var(--els-blue); }
.pub-nav a[aria-current="page"]:not(.btn) { color: var(--els-blue); border-bottom-color: var(--els-blue); font-weight: 600; }

.pub-main { max-width: 1200px; margin: 0 auto; padding: 1.75rem 1.5rem 5rem; }

/* Plain (non-masthead) article page mini-masthead — journal logo/name +
   volume/issue/date inline, matching the reference article page's compact
   in-content identity strip instead of a full-width cyan band. */
.els-article-masthead {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  padding-bottom: 1.2rem;
  margin-bottom: 1.8rem;
  border-bottom: 1px solid var(--els-border);
}
/* article.html/article-preview.html's own compact in-content citation strip
   (volume/issue/page range), shown below the page's regular .els-masthead —
   not a replacement for it. */
.els-article-masthead__mark {
  display: inline-grid;
  place-items: center;
  width: 3.4rem;
  height: 3.4rem;
  border-radius: var(--radius-sm);
  background: var(--els-cyan);
  color: #ffffff;
  font-weight: 700;
  font-size: 1.1rem;
  flex: none;
}
/* Real uploaded logo image, same treatment as .app-header__mark--logo
   above — natural aspect ratio instead of the fixed square/color-fill
   built for the 2-letter text-mark fallback. */
.els-article-masthead__mark--logo {
  background: none;
  box-shadow: none;
  width: auto;
  height: 3.4rem;
  max-width: 10rem;
  object-fit: contain;
  border-radius: 0;
}
.els-article-masthead__name { font-weight: 600; color: var(--els-ink); text-decoration: none; }
.els-article-masthead__name:hover { color: var(--els-blue); }
.els-article-masthead__vol { color: var(--els-ink-soft); font-size: 0.88rem; margin-top: 0.1rem; }

.pub-hero { padding: 1.5rem 0 2rem; border-bottom: 1px solid var(--border-soft); margin-bottom: 1.75rem; }
.pub-hero h1 { font-size: 1.9rem; margin-bottom: 0.4rem; }
.pub-hero__meta { color: var(--ink-soft); font-size: 0.92rem; margin: 0.2rem 0; }
.pub-hero__cta { margin-top: 1rem; }

.pub-hero__eyebrow {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  padding: 0.25rem 0.65rem;
  border-radius: var(--radius-pill);
  margin-bottom: 0.8rem;
}

.pub-section { margin-bottom: 2.25rem; }
.pub-section h2 { margin-bottom: 0.9rem; font-family: var(--font-sans); font-size: 1.25rem; color: var(--els-ink); }

.pub-empty { color: var(--ink-faint); font-style: italic; padding: 1.5rem 0; }

/* "About the journal" two-column intro (journal.html), matching the
   reference's boxed-description + publishing-options layout. */
.els-about-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 1.5rem; margin-bottom: 2.25rem; align-items: start; }
@media (max-width: 820px) { .els-about-grid { grid-template-columns: 1fr; } }
.els-about-panel { background: var(--els-bg-soft); border-radius: var(--radius); padding: 1.5rem 1.6rem; }
.els-about-panel h2 { margin: 0 0 0.75rem; font-size: 1.15rem; font-family: var(--font-sans); color: var(--els-ink); }
.els-about-panel p { color: var(--els-ink-soft); line-height: 1.6; margin: 0 0 0.6rem; }
.els-about-panel__heading { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; }
.els-about-panel__heading h2 { margin-bottom: 0; }

.article-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1rem; }
.article-card {
  background: var(--bg-raised);
  border: 1px solid var(--els-border);
  border-radius: 6px;
  padding: 1.1rem 1.2rem;
  transition: box-shadow 0.15s var(--ease), border-color 0.15s var(--ease), transform 0.15s var(--ease);
}
.article-card:hover { border-color: var(--els-blue); box-shadow: var(--shadow-sm); transform: translateY(-2px); }
.article-card__eyebrow { display: block; font-size: 0.76rem; color: var(--els-ink-soft); margin-bottom: 0.4rem; }
.article-card__eyebrow .els-oa-dot { color: var(--els-green); }
.article-card__journal { font-size: 0.76rem; font-weight: 600; color: var(--els-blue); margin: 0 0 0.2rem; }
.article-card__title { margin: 0 0 0.35rem; font-size: 1rem; font-family: var(--font-sans); }
.article-card__title a { color: var(--els-ink); text-decoration: none; }
.article-card__title a:hover { color: var(--els-blue); text-decoration: underline; }
.article-card__authors { color: var(--els-ink-soft); font-size: 0.88rem; margin: 0.15rem 0; }
.article-card__meta { color: var(--els-ink-soft); font-size: 0.82rem; margin: 0.15rem 0; }
.article-card__abstract { font-size: 0.86rem; color: var(--els-ink-soft); margin-top: 0.5rem; line-height: 1.45; }

/* All-issues archive: accordion-by-year. */
.archive-hero { margin-bottom: 2.25rem; }
.els-issue-year { border-bottom: 1px solid var(--els-border); }
.els-issue-year > summary {
  cursor: pointer;
  list-style: none;
  padding: 1.1rem 0.4rem;
  margin: 0 -0.4rem;
  border-radius: var(--radius);
  color: var(--els-ink);
  display: flex;
  align-items: baseline;
  justify-content: flex-start;
  gap: 0.75rem;
  transition: background 0.15s var(--ease);
}
.els-issue-year > summary:hover { background: var(--bg-soft); }
.els-issue-year > summary::-webkit-details-marker { display: none; }
.els-issue-year__label { font-family: var(--font-serif); font-size: 1.35rem; font-weight: 700; letter-spacing: 0.01em; }
.els-issue-year__count {
  color: var(--accent);
  font-weight: 600;
  font-size: 0.78rem;
  background: var(--accent-soft);
  padding: 0.2rem 0.65rem;
  border-radius: var(--radius-pill);
}
.els-issue-year > summary::after { content: "\25BC"; font-size: 0.65rem; color: var(--accent); margin-left: auto; transition: transform 0.2s var(--ease); }
.els-issue-year[open] > summary::after { transform: rotate(180deg); }

/* Volume grouping inside each year — a small accent-underlined label,
   consistent with the pill/eyebrow accent language used elsewhere. */
.archive-volume-group__title {
  display: inline-block;
  font-size: 0.78rem;
  color: var(--accent);
  font-family: var(--font-sans);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0 0 0.85rem;
  padding-bottom: 0.4rem;
  border-bottom: 2px solid var(--accent-soft);
}

/* Cover-only archive card (real user request: "show only the cover
   image, when I click ... it go to the articles") — each card is now
   nothing but the issue's cover, wrapped in one link straight to that
   issue's article list. Covers sit in a fixed-ratio crop frame so a mix
   of real covers and placeholders lines up evenly across the grid. */
.archive-issue-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 1.5rem; }
.archive-issue-card {
  display: block;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--els-border);
  background: var(--bg-raised);
  box-shadow: var(--shadow-xs);
  text-decoration: none;
  color: inherit;
  transition: box-shadow 0.2s var(--ease), transform 0.2s var(--ease), border-color 0.2s var(--ease);
}
.archive-issue-card:hover { box-shadow: var(--shadow-md, var(--shadow-sm)); transform: translateY(-3px); border-color: var(--accent); }
.archive-issue-card__cover-frame { aspect-ratio: 3 / 4; overflow: hidden; background: var(--els-bg-soft); }
.archive-issue-card__cover {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s var(--ease);
}
.archive-issue-card:hover .archive-issue-card__cover { transform: scale(1.05); }
.archive-issue-card__cover--placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  text-align: center;
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--accent-contrast);
  background: linear-gradient(155deg, var(--accent) 0%, var(--accent-strong) 100%);
  padding: 0.75rem;
}
.archive-issue-card__cover--placeholder em { font-style: normal; font-size: 0.78rem; font-weight: 500; opacity: 0.85; }
.archive-issue-card__label {
  padding: 0.45rem 0.55rem;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--accent);
  background: var(--accent-soft);
  text-align: center;
  border-bottom: 1px solid var(--els-border);
}

/* articles.html: same by-year accordion shell as the Archive page
   (.els-issue-year), one more level of grouping inside each year for
   Volume/Issue — driven by each article's own volume/issue/year fields,
   not a formal issues-table link, so backfilled articles group correctly
   too. */
.pub-page-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 0.5rem; }
.articles-year-body { padding-bottom: 1rem; display: flex; flex-direction: column; gap: 1.5rem; }
.articles-volissue-group__title { font-size: 0.95rem; color: var(--els-ink-soft); font-family: var(--font-sans); font-weight: 600; margin: 0 0 0.75rem; }

/* Add-article modal's dynamic author rows. flex-wrap, not a fixed-column
   grid — a 6-column grid inside a 42rem modal cut off the later columns
   (ORCID/Corresponding/Remove) instead of wrapping them onto a new line.
   Each row gets its own bordered/padded block so wrapped fields still
   read as belonging to the same author. */
.backfill-authors { display: flex; flex-direction: column; gap: 0.6rem; margin-bottom: 0.6rem; }
.backfill-author-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  padding: 0.6rem;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
}
.backfill-author-row input[type="text"] { flex: 1 1 140px; min-width: 0; }
.backfill-author-row__corresponding { display: flex; align-items: center; gap: 0.35rem; font-size: 0.82rem; color: var(--ink-soft); white-space: nowrap; flex: 0 0 auto; }
.backfill-author-row > button { flex: 0 0 auto; }

.policy-body { white-space: pre-wrap; line-height: 1.65; margin-top: 1.2rem; font-size: 0.95rem; color: var(--els-ink); }

/* policies.html: one continuous page, sections stacked in .policies-detail —
   the left nav (position: sticky; its `top` set from JS, since .pub-header
   above it is sticky too and its height varies per journal) just
   scroll-floats you to a section instead of swapping content. */
.policies-layout { display: grid; grid-template-columns: 260px 1fr; gap: 2rem; align-items: start; margin-top: 1rem; }
.policies-nav {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--els-border);
  border-radius: 6px;
  overflow: hidden;
  position: sticky;
}
.policies-nav__item {
  display: block;
  padding: 0.75rem 1rem;
  color: var(--els-ink);
  text-decoration: none;
  font-size: 0.9rem;
  border-bottom: 1px solid var(--els-border);
}
.policies-nav__item:last-child { border-bottom: none; }
.policies-nav__item:hover { background: var(--els-bg-soft); }
.policies-nav__item--active {
  background: var(--els-bg-soft);
  color: var(--els-blue);
  font-weight: 600;
  border-left: 3px solid var(--els-blue);
  padding-left: calc(1rem - 3px);
}
.policies-detail { min-width: 0; }
.policies-detail h2 { margin-top: 0; }
.policies-detail__actions { display: flex; align-items: center; gap: 0.9rem; flex: none; }
.policy-section { margin-top: 2.5rem; padding-top: 2rem; border-top: 1px solid var(--els-border); }
.policy-section:first-child { margin-top: 0; padding-top: 0; border-top: none; }
@media (max-width: 760px) {
  .policies-layout { grid-template-columns: 1fr; }
  /* Single-column stack: the nav no longer has its own column to float
     sticky above, so a sticky position here would just overlap whatever
     section scrolls underneath it instead of sitting beside it. Placed
     after the base .policies-nav rule above so it actually wins — an
     earlier version of this override sat before that rule, where equal
     specificity meant source order let the unconditional sticky rule win
     regardless of the media query. */
  .policies-nav { position: static; }
}

.board-role-group:not(:first-child) { margin-top: 2.25rem; }
.board-role-group h2 { font-size: 1.15rem; margin-bottom: 0.4rem; }
.board-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1rem; margin-top: 1rem; }
.board-card__address { color: var(--els-ink-soft); font-size: 0.85rem; margin: 0.1rem 0; }
.board-card {
  background: var(--bg-raised);
  border: 1px solid var(--els-border);
  border-radius: 6px;
  padding: 1rem 1.15rem;
  transition: box-shadow 0.15s var(--ease), border-color 0.15s var(--ease), transform 0.15s var(--ease);
}
.board-card:hover { border-color: var(--els-blue); box-shadow: var(--shadow-sm); transform: translateY(-2px); }
.board-card h3 { margin: 0 0 0.2rem; font-size: 0.98rem; font-family: var(--font-sans); }
.board-card__role { color: var(--els-blue); font-size: 0.85rem; font-weight: 600; margin: 0.1rem 0; }
.board-card__institution { color: var(--els-ink-soft); font-size: 0.85rem; margin: 0.1rem 0; }
.board-card__email { font-size: 0.82rem; margin: 0.1rem 0; }
.board-card__email a { color: var(--els-blue); }
.board-card__orcid { font-size: 0.78rem; margin: 0.1rem 0; }
.board-card__orcid a { display: inline-flex; align-items: center; gap: 0.35rem; color: var(--ink-faint); text-decoration: none; }
.board-card__orcid a:hover { color: var(--els-blue); }
.board-card__photo {
  width: 3.4rem;
  height: 3.4rem;
  border-radius: var(--radius-pill);
  object-fit: cover;
  display: block;
  margin-bottom: 0.6rem;
  background: var(--els-bg-soft);
}
.board-card__photo--placeholder {
  display: grid;
  place-items: center;
  color: var(--els-blue);
  font-weight: 700;
  font-size: 1.2rem;
}

/* journal.html's homepage Editorial Board section — full-bleed (breaks out
   of .pub-main's own max-width/padding via the negative-margin technique)
   solid-color band using the active journal's brand color, falling back to
   this app's shared accent when a journal hasn't configured one. */
.els-board-home {
  --els-board-home-bg: var(--accent);
  position: relative;
  left: 50%;
  right: 50%;
  width: 100vw;
  margin-left: -50vw;
  margin-right: -50vw;
  margin-top: 2.5rem;
  margin-bottom: 2.5rem;
  background: var(--els-board-home-bg);
  color: #ffffff;
}
.els-board-home__inner { max-width: 1200px; margin: 0 auto; padding: 3rem 1.5rem; }
.els-board-home__head { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem 1.5rem; margin-bottom: 1.75rem; }
.els-board-home__head h2 { margin: 0; font-size: 1.4rem; color: #ffffff; }
.els-board-home__link { color: #ffffff; font-weight: 600; text-decoration: none; opacity: 0.92; white-space: nowrap; }
.els-board-home__link:hover { opacity: 1; text-decoration: underline; }
.els-board-home__subhead { margin: 2rem 0 1rem; font-size: 1.1rem; color: #ffffff; opacity: 0.95; }
.els-board-home__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem 2.25rem; }
@media (max-width: 900px) { .els-board-home__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .els-board-home__grid { grid-template-columns: 1fr; } }
.els-board-home__member { display: flex; align-items: flex-start; gap: 1rem; }
.els-board-home__photo {
  width: 4.25rem;
  height: 4.25rem;
  flex: none;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  background: rgba(255, 255, 255, 0.18);
}
.els-board-home__photo--placeholder { display: grid; place-items: center; font-weight: 700; font-size: 1.4rem; color: #ffffff; }
.els-board-home__info { min-width: 0; padding-top: 0.15rem; }
.els-board-home__name { font-weight: 700; font-size: 1.02rem; color: #ffffff; margin-bottom: 0.2rem; }
.els-board-home__line { font-size: 0.86rem; color: #ffffff; opacity: 0.88; line-height: 1.45; }

.journal-badge {
  display: inline-block;
  vertical-align: middle;
  font-family: var(--font-sans);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  padding: 0.25rem 0.65rem;
  border-radius: var(--radius-pill);
  margin-left: 0.6rem;
}
.journal-badge:empty { display: none; }

.search-form { display: flex; gap: 0.6rem; margin: 1rem 0 1.75rem; }
.search-form input[type="search"] {
  flex: 1;
  padding: 0.6rem 0.9rem;
  border: 1px solid var(--els-border);
  border-radius: var(--radius-sm);
  background: var(--bg-raised);
  color: var(--els-ink);
  font-size: 0.94rem;
}
.search-form input[type="search"]:focus { outline: none; box-shadow: 0 0 0 3.5px color-mix(in srgb, var(--els-blue) 20%, transparent); border-color: var(--els-blue); }
.search-form .btn--primary { background: var(--els-blue); border-color: var(--els-blue); }
.search-form .btn--primary:hover { background: var(--els-blue-hover); border-color: var(--els-blue-hover); }

.pub-article__type {
  display: inline-block;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--accent);
  background: var(--accent-soft);
  padding: 0.3rem 0.7rem;
  border-radius: var(--radius-pill);
  margin-bottom: 0.9rem;
}
/* Same pill treatment as .pub-article__type above, green instead of the
   accent color — mirrors the "• Open access" eyebrow text articleCard()
   shows on every article list/card view (article-card__eyebrow .els-oa-dot
   below); the individual article page had no equivalent of its own. */
.pub-article__oa {
  display: inline-block;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--els-green);
  background: color-mix(in srgb, var(--els-green) 16%, transparent);
  padding: 0.3rem 0.7rem;
  border-radius: var(--radius-pill);
  margin-bottom: 0.9rem;
  margin-left: 0.5rem;
}
.pub-article h1 { font-size: 1.85rem; margin-bottom: 0.7rem; font-family: var(--font-sans); color: var(--els-ink); line-height: 1.3; }
.pub-article__authors { font-size: 1.05rem; color: var(--els-ink-soft); margin: 0.2rem 0; }
.pub-article__authors sup { font-size: 0.7em; margin-left: 0.05em; }
.pub-article__corresponding-mark { color: var(--accent); font-weight: 700; }
.pub-article__author-block { margin: 0.2rem 0 1.1rem; }
.pub-article__affiliations {
  list-style: none;
  counter-reset: aff;
  padding: 0;
  margin: 0.5rem 0 0;
  font-size: 0.82rem;
  color: var(--els-ink-soft);
}
.pub-article__affiliations li { counter-increment: aff; padding-left: 1.3em; text-indent: -1.3em; margin-bottom: 0.15rem; }
.pub-article__affiliations li::before { content: counter(aff) ". "; color: var(--accent); font-weight: 600; }
.pub-article__corresponding-note { font-size: 0.82rem; color: var(--els-ink-soft); margin: 0.4rem 0 0; }
.pub-article__corresponding-note a { color: var(--els-blue); }
.pub-article__meta { color: var(--els-ink-soft); font-size: 0.88rem; margin: 0 0 0.6rem; }
.pub-article__doi {
  display: block;
  overflow-wrap: anywhere;
  margin: 0 0 0.6rem;
  padding: 0.4rem 0.75rem;
  font-size: 0.82rem;
  line-height: 1.4;
  background: var(--accent-soft);
  border-radius: 6px;
}
.pub-article__doi a { color: var(--accent); font-weight: 600; }
.pub-article__abstract { margin: 1.5rem 0; padding: 1.35rem 1.5rem; background: var(--els-bg-soft); border-radius: 8px; border-left: 4px solid var(--accent); }
.pub-article__abstract h2 { font-size: 1.05rem; font-family: var(--font-sans); margin: 0 0 0.5rem; }
.pub-article__abstract p { line-height: 1.65; margin: 0; }
.els-keyword-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.8rem 0 1.2rem; }
.els-keyword-chip {
  display: inline-block;
  font-size: 0.82rem;
  color: var(--els-ink-soft);
  background: var(--els-bg-soft);
  border: 1px solid var(--els-border);
  border-radius: var(--radius-pill);
  padding: 0.25rem 0.75rem;
  transition: border-color 0.15s var(--ease), color 0.15s var(--ease);
}
.els-keyword-chip:hover { border-color: var(--accent); color: var(--accent); }
.pub-article__dates { font-size: 0.85rem; color: var(--ink-soft); margin: 0 0 0.6rem; }
.pub-article__license { font-size: 0.85rem; color: var(--ink-faint); margin: 0; }

/* Two-column ScienceDirect-style layout: a reading column for title/
   authors/abstract, and a sticky sidebar holding the actions a reader
   actually comes to an article page to use (download/share/cite/DOI)
   instead of those being scattered as full-width sections underneath. */
.pub-article { max-width: 74rem; margin: 0 auto; }
.pub-article__layout { display: grid; grid-template-columns: 1fr 19rem; gap: 2.5rem; align-items: start; }
.pub-article__main { min-width: 0; max-width: 44rem; }
.pub-article__sidebar { position: sticky; top: 1.25rem; display: flex; flex-direction: column; gap: 1rem; }
@media (max-width: 860px) {
  .pub-article__layout { grid-template-columns: 1fr; }
  .pub-article__main { max-width: none; }
  .pub-article__sidebar { position: static; }
}
.pub-article__sidebar-card { background: var(--els-bg-soft); border-radius: 8px; padding: 1.1rem 1.25rem; }
.pub-article__sidebar-card h3 { font-size: 0.88rem; font-family: var(--font-sans); margin: 0 0 0.65rem; }
.pub-article__sidebar-card--download { background: var(--accent-soft); }
.pub-article__download-list { display: flex; flex-direction: column; gap: 0.5rem; }
.pub-article__download-btn { width: 100%; justify-content: center; font-size: 0.92rem; }
.pub-article__cite-links { display: flex; flex-direction: column; gap: 0.5rem; margin-top: 0.2rem; }
.pub-article__cite-links .btn { width: 100%; justify-content: center; }
.pub-article__cite-links .btn--secondary { border-color: var(--els-blue); color: var(--els-blue); background: transparent; }
.pub-article__cite-links .btn--secondary:hover { background: color-mix(in srgb, var(--els-blue) 10%, transparent); }

/* Articles and Archives Module additions ------------------------------- */

.pub-article__author:not(:last-child)::after { content: ""; }
.pub-article__orcid { display: inline-flex; align-items: center; vertical-align: middle; margin-left: 0.3rem; opacity: 0.85; transition: opacity 0.15s var(--ease); }
.pub-article__orcid:hover { opacity: 1; }

.pub-article__notice {
  padding: 0.9rem 1.1rem;
  border-radius: 6px;
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 1.2rem;
  border: 1px solid transparent;
}
.pub-article__notice--retracted { background: color-mix(in srgb, var(--danger, #b3261e) 12%, transparent); border-color: var(--danger, #b3261e); color: var(--danger, #b3261e); }
.pub-article__notice--withdrawn { background: color-mix(in srgb, var(--danger, #b3261e) 12%, transparent); border-color: var(--danger, #b3261e); color: var(--danger, #b3261e); }
.pub-article__notice--corrected { background: color-mix(in srgb, var(--els-blue) 12%, transparent); border-color: var(--els-blue); color: var(--els-blue); }
.pub-article__notice--preview { background: color-mix(in srgb, var(--warn, #9a6700) 15%, transparent); border-color: var(--warn, #9a6700); color: var(--warn, #9a6700); }

.pub-article__share { display: flex; gap: 0.5rem; flex-wrap: wrap; margin: 0.6rem 0 1rem; }
.pub-article__jel-label { font-size: 0.78rem; color: var(--els-ink-soft); align-self: center; }

.pub-cite-modal__text { width: 100%; font-family: var(--font-mono, monospace); font-size: 0.85rem; resize: vertical; }

.article-card__doi { font-size: 0.78rem; color: var(--ink-faint); margin: 0.15rem 0; }
.article-card__actions { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.75rem; }

.articles-filter-bar {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  align-items: center;
  margin: 0.75rem 0 1.5rem;
  padding: 0.9rem 1rem;
  background: var(--els-bg-soft);
  border-radius: 6px;
}
.articles-filter-bar input, .articles-filter-bar select {
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--els-border);
  border-radius: 5px;
  background: var(--bg-raised);
  color: var(--els-ink);
  font-size: 0.85rem;
  min-width: 0;
  flex: 1 1 140px;
}
.articles-filter-bar input[type="search"] { flex: 2 1 220px; }

.pub-pagination { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-top: 1.5rem; font-size: 0.85rem; color: var(--els-ink-soft); }

/* Archive: Year -> Volume -> Issue (three levels, spec §18) */
.archive-year-body { padding-bottom: 1rem; display: flex; flex-direction: column; gap: 1.25rem; }
.archive-volume-group__title { font-size: 0.95rem; color: var(--els-ink-soft); font-family: var(--font-sans); font-weight: 600; margin: 0 0 0.5rem; }

.els-issue-cover { max-width: 220px; width: 100%; height: auto; border-radius: 6px; margin-bottom: 1rem; display: block; }

/* ---------------------------------------------------------------------------
   Shared public-site footer (new — renderFooter() in public.js, appended by
   every render function). Matches the reference's ISSN/copyright line +
   multi-column link list + publisher wordmark.
   --------------------------------------------------------------------------- */
.els-footer { margin-top: 3rem; padding-top: 1.75rem; border-top: 1px solid var(--els-border); }
.els-footer__logo { height: 3.2rem; width: auto; max-width: 13rem; object-fit: contain; margin-bottom: 1.25rem; }
.els-footer__cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1.5rem; margin-bottom: 1.75rem; }
.els-footer__col h3 { font-size: 0.85rem; margin: 0 0 0.6rem; color: var(--els-ink); }
.els-footer__col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
.els-footer__col a { color: var(--els-blue); text-decoration: none; font-size: 0.88rem; }
.els-footer__col a:hover { text-decoration: underline; }
.els-footer__legal { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 0.5rem; padding-top: 1.25rem; border-top: 1px solid var(--els-border); color: var(--els-ink-soft); font-size: 0.8rem; }

/* journal.html's "Get involved" (author/editor portal entry points) — a
   dedicated class family so it never collides with index.html's unrelated
   .portal-card (the 4-tool hub, explicitly out of this redesign's scope). */
.els-getinvolved-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.25rem; margin-top: 1rem; }
.els-getinvolved-card {
  background: var(--bg-raised);
  border: 1px solid var(--els-border);
  border-radius: 6px;
  padding: 1.5rem 1.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.els-getinvolved-card__eyebrow { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--els-blue); }
.els-getinvolved-card h3 { font-size: 1.1rem; margin: 0; font-family: var(--font-sans); color: var(--els-ink); }
.els-getinvolved-card p { color: var(--els-ink-soft); font-size: 0.92rem; margin: 0; line-height: 1.5; }
.els-getinvolved-card__actions { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 0.2rem; }
.els-getinvolved-card__actions .btn--primary { background: var(--els-blue); border-color: var(--els-blue); }
.els-getinvolved-card__actions .btn--primary:hover { background: var(--els-blue-hover); border-color: var(--els-blue-hover); }

/* ===========================================================================
   Author portal — login/register/dashboard/submission wizard (spec §9).
   Reuses .steps/.step/.field/.badge/.chip etc. from above; only new
   component classes and input[type="password"] (missing from the base
   input selector list) are added here.
   =========================================================================== */

input[type="password"] {
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-raised);
  color: var(--ink);
  font-size: 0.94rem;
  font-family: inherit;
}
input[type="password"]:focus { outline: none; box-shadow: var(--shadow-focus); border-color: var(--accent); }

.auth-shell { max-width: 420px; margin: 3.5rem auto; padding: 0 1.5rem; }
.auth-shell__top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem; }
.auth-card {
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 2rem 2.2rem;
}
.auth-card h1 { font-size: 1.4rem; margin-bottom: 0.3rem; }
.auth-card__hint { color: var(--ink-soft); font-size: 0.88rem; margin: 0 0 1.4rem; }
.auth-card__footer { margin-top: 1.2rem; font-size: 0.88rem; color: var(--ink-soft); }
.auth-error { color: var(--err); font-size: 0.85rem; min-height: 1.1em; margin: 0.3rem 0 0.6rem; }

.author-topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.1rem 1.75rem;
  border-bottom: 1px solid var(--border-soft);
  background: color-mix(in srgb, var(--bg-soft) 92%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  position: sticky;
  top: 0;
  z-index: 30;
}
.author-topbar__user { display: flex; align-items: center; gap: 0.6rem; font-size: 0.88rem; color: var(--ink-soft); flex-wrap: wrap; justify-content: flex-end; }

/* Real user request: submit.html's header should show the specific
   journal you're submitting to (unlike account.html, which stays the
   generic platform identity since it spans every journal) — applied by
   applyTopbarBrandColor (author.js). */
.author-topbar--branded { border-bottom-color: transparent; color: #ffffff; }
.author-topbar--branded .pub-header__brand,
.author-topbar--branded .pub-header__brand span { color: #ffffff; }
.author-topbar--branded .author-topbar__user { color: rgba(255, 255, 255, 0.85); }
.author-topbar--branded .theme-toggle { background: rgba(255, 255, 255, 0.14); border-color: rgba(255, 255, 255, 0.3); color: #ffffff; }
.author-topbar--branded .theme-toggle:hover { border-color: #ffffff; }
.author-topbar--branded .account-menu__toggle { color: #ffffff; }
.author-topbar--branded .account-menu__toggle:hover,
.author-topbar--branded .account-menu__toggle:focus-visible { border-color: rgba(255, 255, 255, 0.4); background: rgba(255, 255, 255, 0.14); }
.author-topbar--branded .account-menu__avatar { background: rgba(255, 255, 255, 0.22); color: #ffffff; }

/* Editorial Publishing Access: shared journal switcher (spec §54) mounted
   into the same topbar every /editorial-family page already uses. */
.journal-switcher select {
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--els-border, var(--border-soft));
  border-radius: 5px;
  background: var(--bg-raised);
  color: var(--ink);
  font-size: 0.82rem;
}

.submission-groups { display: flex; flex-direction: column; gap: 2rem; margin-top: 1.5rem; }
.submission-group h2 { font-size: 1.05rem; }
.submission-list { display: flex; flex-direction: column; gap: 0.6rem; }
.submission-card {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 0.9rem 1.1rem;
  box-shadow: var(--shadow-xs);
  transition: transform 0.15s var(--ease), box-shadow 0.15s var(--ease), border-color 0.15s var(--ease);
}
.submission-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); border-color: var(--ink-faint); }
.submission-card__title { font-weight: 600; }
.submission-card__code { color: var(--ink-faint); font-size: 0.8rem; font-family: var(--font-mono); }

.author-card {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 1rem 1.2rem;
  margin-bottom: 1rem;
  background: var(--bg-raised);
  box-shadow: var(--shadow-xs);
}
.author-card__row { display: flex; gap: 1rem; flex-wrap: wrap; }
.author-card__footer { display: flex; justify-content: space-between; align-items: center; margin-top: 0.5rem; }

.declaration-field { margin-bottom: 1.3rem; }
.declaration-field label { font-weight: 600; font-size: 0.9rem; display: block; margin-bottom: 0.35rem; }

.file-upload-row {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.8rem 0;
  border-bottom: 1px solid var(--border-soft);
  flex-wrap: wrap;
}
.file-upload-row__label { min-width: 140px; font-weight: 600; font-size: 0.88rem; }
.attached-files { list-style: none; padding: 0; margin: 1rem 0; }
.attached-files li { padding: 0.35rem 0; font-size: 0.88rem; color: var(--ink-soft); }

.reviewer-row { display: flex; gap: 0.6rem; margin-bottom: 0.6rem; flex-wrap: wrap; align-items: flex-end; }
.reviewer-row .field { margin-bottom: 0; }

.review-summary dt { color: var(--ink-faint); font-size: 0.8rem; margin-top: 0.9rem; }
.review-summary dd { margin: 0.15rem 0 0; font-size: 0.94rem; }

.btn--hidden { display: none; }

/* ===========================================================================
   Editorial Screening + Peer Review Workflow (spec §11-14).
   =========================================================================== */

.staff-nav { display: flex; gap: 0.6rem; margin-bottom: 1.5rem; }
.staff-nav:empty { display: none; }

.queue-groups { display: flex; flex-direction: column; gap: 2rem; margin-top: 1.5rem; }
.queue-group h2 { font-size: 1.05rem; }
.queue-list { display: flex; flex-direction: column; gap: 0.6rem; }
.queue-card {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 0.9rem 1.1rem;
  text-decoration: none;
  color: inherit;
  box-shadow: var(--shadow-xs);
  transition: transform 0.15s var(--ease), box-shadow 0.15s var(--ease), border-color 0.15s var(--ease);
}
.queue-card:hover { border-color: var(--accent); transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.queue-card__title { font-weight: 600; }
.queue-card__code { color: var(--ink-faint); font-size: 0.8rem; font-family: var(--font-mono); }

.detail-section { margin-bottom: 2rem; padding-bottom: 1.5rem; border-bottom: 1px solid var(--border-soft); }
.detail-section h2 { font-size: 1.1rem; }

/* Real user request: account.html's Name/Email, as a small profile card
   (avatar + name + email) instead of a plain two-row definition list. */
.account-profile-card {
  display: flex;
  align-items: center;
  gap: 1rem;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  background: var(--bg-raised);
  box-shadow: var(--shadow-sm);
  padding: 1rem 1.2rem;
}
.account-profile-card__avatar {
  flex: none;
  width: 3.4rem;
  height: 3.4rem;
  border-radius: 50%;
  display: inline-grid;
  place-items: center;
  background: linear-gradient(155deg, var(--accent) 0%, var(--accent-strong, var(--accent)) 100%);
  color: var(--accent-contrast, #ffffff);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.account-profile-card__name { font-size: 1.15rem; font-weight: 700; color: var(--ink); font-family: var(--font-serif); }
.account-profile-card__email { font-size: 0.9rem; color: var(--ink-soft); margin-top: 0.15rem; }

/* Real user request: the ORCID row, same card treatment as the Account
   profile card above instead of a bare inline icon/link/badge row. */
.account-orcid-card {
  display: flex;
  align-items: center;
  gap: 1rem;
  border: 1px solid var(--border-soft);
  border-left: 4px solid #A6CE39;
  border-radius: 10px;
  background: var(--bg-raised);
  box-shadow: var(--shadow-sm);
  padding: 1rem 1.2rem;
  flex-wrap: wrap;
}
.account-orcid-card--unverified { border-left-color: var(--border-soft); }
.account-orcid-card__icon { flex: none; width: 2.6rem; height: 2.6rem; }
.account-orcid-card__icon .orcid-icon { width: 100%; height: 100%; }
.account-orcid-card__info { display: flex; flex-direction: column; gap: 0.3rem; flex: 1; min-width: 0; }
.account-orcid-card__id { font-weight: 700; color: var(--ink); text-decoration: none; }
.account-orcid-card__id:hover { color: var(--accent); }
.account-orcid-card__id--empty { font-weight: 500; color: var(--ink-faint); }

/* Real user request: account.html's Roles list, grouped one card per
   journal (or Platform-wide/a publisher) instead of one flat "Role —
   Journal" list per row — each card accented in that journal's own brand
   color, with its real logo and each role shown as a pill badge. */
.account-roles { display: flex; flex-direction: column; gap: 0.85rem; }
.account-roles__card {
  --role-card-accent: var(--accent);
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--role-card-accent);
  border-radius: 10px;
  background: var(--bg-raised);
  box-shadow: var(--shadow-sm);
  padding: 0.9rem 1.1rem;
  transition: box-shadow 0.15s var(--ease), transform 0.15s var(--ease);
}
.account-roles__card:hover { box-shadow: var(--shadow-md, var(--shadow-sm)); transform: translateY(-1px); }
.account-roles__card-header { display: flex; align-items: center; gap: 0.65rem; margin-bottom: 0.65rem; }
.account-roles__card-header h3 { margin: 0; font-size: 1rem; }
.account-roles__card-logo { width: 2.1rem; height: 2.1rem; object-fit: contain; border-radius: 6px; flex: none; }
.account-roles__card-icon {
  display: inline-grid;
  place-items: center;
  width: 2.1rem;
  height: 2.1rem;
  flex: none;
  border-radius: 6px;
  background: color-mix(in srgb, var(--role-card-accent) 16%, transparent);
  color: var(--role-card-accent);
  font-size: 1rem;
}
.account-roles__pills { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.account-roles__pills .badge { background: color-mix(in srgb, var(--role-card-accent) 14%, transparent); color: var(--role-card-accent); }
.detail-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 0.8rem; }

.assignment-row, .review-row {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  padding: 0.7rem 1rem;
  margin-bottom: 0.6rem;
  background: var(--bg-raised);
  transition: box-shadow 0.15s var(--ease), border-color 0.15s var(--ease);
}
.assignment-row:hover, .review-row:hover { box-shadow: var(--shadow-xs); border-color: var(--ink-faint); }
.assignment-row__meta, .review-row__meta { color: var(--ink-faint); font-size: 0.8rem; }
.assignment-row--done { background: var(--accent-soft); border-color: var(--accent); }
.assignment-row--done .pub-empty { color: var(--accent); font-style: normal; font-weight: 600; padding: 0.4rem 0 0; }

.decision-form textarea { width: 100%; }

/* Editorial board management (manage-board.html) — distinct class names
   from .board-card/.board-grid (the public-site cards) so this admin page
   stays on the portal's --accent tokens rather than the public site's
   --els-* palette. */
.board-preview-banner { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.board-manage-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem; }
.board-manage-toolbar h2 { margin: 0; }
.board-manage-toolbar__search { flex: 1 1 220px; max-width: 20rem; margin: 0; }
.board-manage-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1rem; }
.board-manage-card {
  display: flex;
  gap: 0.8rem;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 1rem;
  background: var(--bg-raised);
  box-shadow: var(--shadow-xs);
  transition: transform 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.board-manage-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-sm); }
.board-manage-card--retired { opacity: 0.6; }
/* Journal cards carry more rows (avatar+name, publisher, meta, badges,
   actions) than the board-member cards this class was built for — stacking
   them in a column (rather than the default row, which stretches every
   direct child incl. the action buttons to the tallest sibling's height)
   keeps the buttons their normal size instead of ballooning to card height. */
.board-manage-card--journal { flex-direction: column; align-items: stretch; }
.board-manage-card__header { display: flex; gap: 0.8rem; align-items: flex-start; }
.board-manage-card__body { flex: 1; min-width: 0; }
.board-manage-card__name { font-weight: 650; }
.board-manage-card__email { color: var(--ink-soft); font-size: 0.85rem; word-break: break-all; }
.board-manage-card__publisher { color: var(--accent); font-size: 0.85rem; font-weight: 600; margin: 0.1rem 0; }
.board-manage-card__meta { color: var(--ink-soft); font-size: 0.85rem; margin-top: 0.15rem; }
.board-manage-card__badges { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-top: 0.5rem; }
.board-manage-card__actions { display: flex; gap: 0.5rem; margin-top: 0.6rem; flex-wrap: wrap; }

.journal-manage-avatar {
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-sm);
  flex: none;
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 1rem;
  color: #fff;
  background: var(--accent);
}

.board-member-photo {
  width: 3.2rem;
  height: 3.2rem;
  border-radius: var(--radius-pill);
  object-fit: cover;
  flex: none;
  background: var(--accent-soft);
}
.board-member-photo--placeholder {
  display: grid;
  place-items: center;
  color: var(--accent);
  font-weight: 700;
  font-size: 1.1rem;
}
.board-member-photo--sm { width: 2.4rem; height: 2.4rem; display: inline-block; vertical-align: middle; margin-right: 0.5rem; }

/* The edit/add-member modal form — a clean 2-column field grid, unlike the
   generic .detail-actions flex-wrap row this replaced (which, crammed into
   a ~280px board-manage-card, wrapped label/input text into an overlapping
   mess). */
.board-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9rem 1rem; }
.board-form-grid .field--full { grid-column: 1 / -1; }
.board-form-photo-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.8rem; margin-top: 0.3rem; }
.board-form-photo-row input[type="file"] { min-width: 0; max-width: 100%; }
.board-form-checkbox { display: flex; align-items: center; gap: 0.5rem; font-size: 0.92rem; cursor: pointer; }
.board-form-checkbox input { width: auto; }

/* editorial-branding.html: Journal Color */
.brand-color-row { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; margin-top: 0.5rem; }
.brand-color-row input[type="color"] { width: 2.6rem; height: 2.4rem; padding: 0.15rem; border: 1px solid var(--els-border); border-radius: var(--radius-sm); background: none; cursor: pointer; }
.brand-color-row input[type="text"] { width: 12rem; }
.brand-color-preview { width: 2.4rem; height: 2.4rem; border-radius: 50%; border: 1px solid var(--els-border); flex: none; }

/* manage-issues.html: assign/order an issue's articles (spec §24) */
.issue-articles-columns { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin: 1rem 0; }
/* Grid tracks default to min-width: auto, not 0 — without this, a long
   unbroken article title stops the column (and the whole modal) from
   shrinking to fit, instead growing past the modal's edge. */
.issue-articles-columns > div { min-width: 0; }
@media (max-width: 700px) { .issue-articles-columns { grid-template-columns: 1fr; } }
.issue-articles-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.4rem; max-height: 320px; overflow-y: auto; }
.issue-articles-list li { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.45rem 0.6rem; border: 1px solid var(--els-border); border-radius: 5px; font-size: 0.85rem; }
.issue-articles-list li span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.issue-articles-list li > div { display: flex; gap: 0.3rem; flex: 0 0 auto; }

/* ===========================================================================
   Landing page (index.html) — hub linking to the public site and the
   author/editor portals (production is deliberately not linked here, same
   as journal.html's "Get involved" section — it's reached only from inside
   an accepted submission's own workspace, never browsed to directly).
   SpringerLink-style: search-first hero, teal header, clean card sections.
   See --spr-* tokens at the top of this file for why these colors are
   Springer's known brand teal rather than a pixel-sampled value.
   =========================================================================== */

.spr-header { background: var(--spr-teal); border-bottom-color: var(--spr-teal-dark); }
.spr-header .pub-header__brand { color: #ffffff; font-weight: 700; }
.spr-header .app-header__mark { background: rgba(255, 255, 255, 0.18); color: #ffffff; }
.spr-header .theme-toggle { background: rgba(255, 255, 255, 0.14); border-color: rgba(255, 255, 255, 0.32); color: #ffffff; }
.spr-header .theme-toggle:hover { border-color: #ffffff; }
.spr-header .account-menu__toggle { color: #ffffff; }
.spr-header .account-menu__toggle:hover, .spr-header .account-menu__toggle:focus-visible { border-color: rgba(255, 255, 255, 0.4); background: rgba(255, 255, 255, 0.14); }
.spr-header .auth-links .btn--secondary { background: rgba(255, 255, 255, 0.14); border-color: rgba(255, 255, 255, 0.32); color: #ffffff; }

.spr-search-hero {
  background: linear-gradient(155deg, var(--spr-teal) 0%, var(--spr-teal-dark) 100%);
  padding: 3.2rem 1.75rem 3.6rem;
  text-align: center;
}
.spr-search-hero__inner { max-width: 46rem; margin: 0 auto; }
.spr-search-hero h1 { color: #ffffff; font-family: var(--font-sans); font-size: 1.9rem; margin: 0 0 0.6rem; }
.spr-search-hero__stats { color: rgba(255, 255, 255, 0.88); font-size: 0.92rem; margin: 0 0 1.5rem; min-height: 1.3em; }
.spr-search-form { display: flex; gap: 0.6rem; max-width: 38rem; margin: 0 auto; }
.spr-search-form input {
  flex: 1;
  padding: 0.85rem 1.1rem;
  border-radius: var(--radius-pill);
  border: none;
  font-size: 1rem;
  background: #ffffff;
  color: var(--spr-ink);
  box-shadow: var(--shadow-md);
}
.spr-search-form input:focus { outline: none; box-shadow: 0 0 0 3.5px rgba(255, 255, 255, 0.45), var(--shadow-md); }
.spr-search-form .btn--primary {
  background: var(--spr-ink);
  border-color: var(--spr-ink);
  border-radius: var(--radius-pill);
  padding: 0.85rem 1.6rem;
}
.spr-search-form .btn--primary:hover { background: #000000; }

.spr-section { margin: 2.5rem 0; }
.spr-section--soft { background: var(--spr-bg-soft); border-radius: var(--radius-lg); padding: 2rem 1.75rem; }
.spr-section h2 { font-family: var(--font-sans); font-size: 1.35rem; color: var(--spr-ink); margin: 0 0 1.1rem; }

.index-journals-section--hidden, .index-latest-section--hidden { display: none; }

.spr-journal-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 1.1rem; }
.spr-journal-card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  background: var(--bg-raised);
  border: 1px solid var(--spr-border);
  border-radius: var(--radius);
  padding: 1.4rem 1.5rem;
  text-decoration: none;
  color: var(--spr-ink);
  transition: box-shadow 0.15s var(--ease), border-color 0.15s var(--ease), transform 0.15s var(--ease);
}
.spr-journal-card:hover { border-color: var(--spr-teal); box-shadow: var(--shadow-sm); transform: translateY(-2px); }
.spr-journal-card img { max-height: 2.2rem; width: auto; max-width: 70%; object-fit: contain; align-self: flex-start; }
.spr-journal-card h3 { margin: 0; font-size: 1.05rem; font-family: var(--font-sans); }
.spr-journal-card__meta { margin: 0; font-size: 0.82rem; color: var(--spr-ink-soft); }

.spr-cta-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.25rem; }
.spr-cta-card {
  background: var(--bg-raised);
  border: 1px solid var(--spr-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  padding: 1.5rem 1.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.spr-cta-card:hover { box-shadow: var(--shadow-sm); transform: translateY(-2px); }
.spr-cta-card__eyebrow {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--spr-teal);
}
.spr-cta-card h3 { font-size: 1.1rem; margin: 0; font-family: var(--font-sans); }
.spr-cta-card p { color: var(--ink-soft); font-size: 0.92rem; margin: 0; line-height: 1.5; }
.spr-cta-card__actions { display: flex; gap: 0.6rem; flex-wrap: wrap; margin-top: 0.2rem; }

@media (max-width: 640px) {
  .spr-search-hero h1 { font-size: 1.5rem; }
  .spr-search-form { flex-direction: column; }
}

/* ===========================================================================
   Editorial Publishing Access (editorial-dashboard/-articles/-article-editor/
   -media.html, plus manage-issues.html additions) */

.audit-event-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.5rem; max-height: 420px; overflow-y: auto; }
.audit-event { font-size: 0.85rem; padding: 0.5rem 0; border-bottom: 1px solid var(--border-soft); }
.audit-event__action { font-weight: 600; }
.audit-event__reason { color: var(--ink-soft); font-style: italic; margin-top: 0.2rem; }

/* Articles Management table */
.editorial-filter-bar { display: flex; gap: 0.6rem; flex-wrap: wrap; align-items: center; margin: 0.75rem 0 1rem; }
.editorial-filter-bar input, .editorial-filter-bar select { padding: 0.4rem 0.6rem; border: 1px solid var(--border-soft); border-radius: 5px; background: var(--bg-raised); color: var(--ink); font-size: 0.85rem; }
.editorial-quick-filters { display: flex; gap: 0.4rem; flex-wrap: wrap; margin-bottom: 1rem; }
.editorial-quick-filters button.active { background: var(--accent); color: var(--accent-contrast, #fff); border-color: var(--accent); }
.editorial-articles-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.editorial-articles-table th, .editorial-articles-table td { text-align: left; padding: 0.55rem 0.7rem; border-bottom: 1px solid var(--border-soft); vertical-align: top; }
.editorial-articles-table th { color: var(--ink-soft); font-weight: 600; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em; }
.editorial-articles-table td.actions { white-space: nowrap; }
.editorial-articles-table__code { white-space: nowrap; font-family: var(--font-mono, monospace); font-size: 0.82rem; color: var(--ink-soft); }
/* Generic dropdown-menu building block — originally table-scoped, promoted
   to a bare reusable class shared with the account menu (Authentication-
   Aware Navigation Bar spec §2/§19) rather than duplicating the same
   position/box/keyboard-close styling under a second class name. */
.dropdown { position: relative; display: inline-block; }
.dropdown__menu {
  position: absolute; right: 0; top: 100%; z-index: 20; min-width: 190px;
  background: var(--bg-raised); border: 1px solid var(--border-soft); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-sm); display: flex; flex-direction: column; padding: 0.3rem;
}
.dropdown__menu a, .dropdown__menu button {
  text-align: left; background: none; border: none; padding: 0.4rem 0.6rem; font-size: 0.85rem; color: var(--ink); cursor: pointer; border-radius: 4px; text-decoration: none; display: block;
}
.dropdown__menu a:hover, .dropdown__menu button:hover { background: var(--bg-soft); }
.dropdown__menu button.danger { color: var(--err); }
.dropdown__menu--hidden { display: none; }

/* Account menu (top-right, public pages) */
.pub-auth-area:empty { min-width: 1px; } /* LOADING state: genuinely empty, no layout jump once content arrives */
.auth-links { display: flex; gap: 0.5rem; align-items: center; }
.account-menu { font-size: 0.88rem; min-width: 0; }
.account-menu__toggle {
  display: flex; align-items: center; gap: 0.45rem; background: none; border: 1px solid transparent; border-radius: var(--radius-sm);
  padding: 0.3rem 0.5rem; color: var(--els-ink, var(--ink)); font-size: 0.88rem; font-weight: 600; cursor: pointer;
  min-width: 0; max-width: 100%;
}
.account-menu__toggle:hover, .account-menu__toggle:focus-visible { border-color: var(--border-soft); background: var(--bg-soft); }
.account-menu .dropdown__menu { min-width: 180px; }
/* A long real name/email must never be able to blow out the header row —
   this was a genuine mobile bug (an unrestrained email pushed the whole
   .ed-header/.pub-nav row to ~880px wide on a 375px viewport, silently
   clipped off-screen by body's overflow-x: hidden with no way to reach it
   at all). Ellipsis-truncated everywhere, not just on mobile, since an
   unbounded label was never actually safe at any width. */
.account-menu__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; max-width: 14rem; }
.account-menu__avatar {
  flex: none; width: 2.3rem; height: 2.3rem; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent-strong, var(--accent));
  display: inline-grid; place-items: center;
  font-size: 0.85rem; font-weight: 700; letter-spacing: 0.02em;
}
.spr-header .account-menu__avatar, .els-masthead .account-menu__avatar { background: rgba(255, 255, 255, 0.22); color: #ffffff; }

/* Article editor */
.article-editor-split { display: flex; gap: 1.5rem; align-items: flex-start; }
.article-editor-split__edit { flex: 1 1 0; min-width: 0; }
.article-editor-split__preview { flex: 1 1 0; min-width: 0; position: sticky; top: 1rem; align-self: flex-start; height: calc(100vh - 2rem); display: flex; flex-direction: column; border: 1px solid var(--border-soft); border-radius: var(--radius); background: var(--bg-raised); overflow: hidden; }
.article-editor-preview__header { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; padding: 0.8rem 1rem; border-bottom: 1px solid var(--border-soft); flex: none; }
.article-editor-preview__header h2 { margin: 0; font-size: 1rem; }
.article-editor-preview__body { flex: 1; min-height: 0; }
.article-editor-preview__frame { display: block; width: 100%; height: 100%; border: 0; background: var(--bg); }
.article-editor-preview__body .ed-empty-state { padding: 2rem 1rem; }
/* Below this width the two halves no longer fit side by side legibly —
   stack the live preview beneath the form instead, at a fixed viewing
   height rather than the desktop sticky full-height panel. */
@media (max-width: 1100px) {
  .article-editor-split { flex-direction: column; }
  .article-editor-split__preview { position: static; height: 32rem; width: 100%; }
}
.article-editor-sections { display: flex; flex-direction: column; gap: 1.75rem; max-width: 60rem; }
.article-editor-section { background: var(--bg-raised); border: 1px solid var(--border-soft); border-radius: var(--radius); padding: 1.25rem 1.4rem; }
.article-editor-section h2 { font-size: 1.05rem; margin: 0 0 1rem; }
.article-editor-actions { position: sticky; bottom: 0; background: var(--surface, var(--bg-raised)); border-top: 1px solid var(--border-soft); padding: 0.9rem 0; display: flex; gap: 0.7rem; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.article-editor-savestate { font-size: 0.8rem; color: var(--ink-soft); }
.editorial-author-row { border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 0.75rem; margin-bottom: 0.6rem; }
.editorial-author-row__main { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.editorial-author-row__main input[type="text"], .editorial-author-row__main input[type="email"] { flex: 1 1 140px; min-width: 0; }
.editorial-affiliation-row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px dashed var(--border-soft); }
.editorial-affiliation-row input { flex: 1 1 110px; min-width: 0; }
.checklist { list-style: none; padding: 0; margin: 0.5rem 0; display: flex; flex-direction: column; gap: 0.35rem; font-size: 0.9rem; }
.checklist__ok::before { content: "✓ "; color: var(--ok, #2e7d32); }
.checklist__error::before { content: "✕ "; color: var(--err); }
.checklist__warning::before { content: "! "; color: var(--warn); }
.checklist__summary { font-weight: 600; margin-top: 0.5rem; }

/* Media Library */
.media-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; margin-top: 1rem; }
.media-card { border: 1px solid var(--border-soft); border-radius: var(--radius); overflow: hidden; background: var(--bg-raised); }
.media-card__preview { width: 100%; height: 120px; object-fit: cover; display: block; background: var(--bg-soft); }
.media-card__preview--file { display: flex; align-items: center; justify-content: center; font-size: 0.78rem; color: var(--ink-soft); }
.media-card__body { padding: 0.6rem 0.7rem; font-size: 0.8rem; }
.media-card__name { font-weight: 600; word-break: break-all; }
.media-card__meta { color: var(--ink-soft); margin-top: 0.2rem; }
.media-card__alt { width: 100%; margin-top: 0.4rem; font-size: 0.78rem; }

/* Journal Branding (Editable Journal Logo and Branding spec) */
.branding-section__heading { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; margin-bottom: 0.9rem; }
.branding-section__heading h2 { margin: 0; }
.branding-previews { display: grid; grid-template-columns: 1fr 1fr; gap: 1.2rem; margin-bottom: 1rem; }
.branding-previews h4 { margin: 0 0 0.4rem; font-size: 0.78rem; color: var(--ink-soft); text-transform: uppercase; letter-spacing: 0.03em; }
.branding-preview {
  min-height: 4.5rem; display: flex; align-items: center; padding: 0.8rem;
  border: 1px dashed var(--border-soft); border-radius: var(--radius-sm); background: var(--bg-soft);
}
.branding-preview img { max-width: 100%; max-height: 6rem; object-fit: contain; }
.branding-preview--hidden { display: none; }
.branding-upload-row { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 0.8rem; }
.branding-upload-row--hidden { display: none; }
.branding-cancel--hidden { display: none; }
.branding-toggle { display: flex; gap: 1.2rem; margin-bottom: 0.8rem; font-size: 0.88rem; }
.branding-toggle label { display: flex; align-items: center; gap: 0.4rem; cursor: pointer; }
.branding-history-details summary { cursor: pointer; font-size: 0.85rem; color: var(--ink-soft); }
.branding-history__list { list-style: none; padding: 0; margin: 0.7rem 0 0; display: flex; flex-direction: column; gap: 0.5rem; }
.branding-history__list li { display: flex; align-items: center; gap: 0.7rem; font-size: 0.85rem; padding: 0.4rem 0; border-bottom: 1px solid var(--border-soft); }
.branding-history__list img { width: 2.4rem; height: 2.4rem; object-fit: contain; background: var(--bg-soft); border-radius: 4px; }
.branding-history__list span { flex: 1; }

/* ===========================================================================
   Editorial Dashboard UI Redesign — persistent sidebar + slim header +
   rebuilt dashboard content. Scoped to the 10 core editorial/staff pages
   (editorial-dashboard/-articles/-article-editor, manage-issues,
   editorial-media, editorial-branding, manage-board, manage-access,
   editor-queue, submission-detail). dashboard.html/submit.html/
   reviewer-workspace.html (author/reviewer portal) deliberately keep the
   existing .author-topbar — a different audience, out of this pass's scope.
   See --ed-* tokens near the top of this file. No reference image was
   actually attached to the spec; built from its very detailed text instead.
   =========================================================================== */

.ed-app { display: flex; flex-direction: column; min-height: 100vh; }

.ed-header {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  padding: 0.65rem 1.5rem;
  background: var(--bg-raised);
  border-bottom: 1px solid var(--border-soft);
  position: sticky;
  top: 0;
  z-index: 40;
}
/* Real user request: the editorial dashboard header should use the
   journal's own brand color, same as the public site's masthead band —
   applyEdHeaderBrandColor (editor.js) sets an inline background here and
   toggles this class. Every child that assumed the plain neutral
   var(--bg-raised) background (brand text, sidebar toggle, home/bell
   icon-buttons, journal switcher, account menu, theme toggle) needs its
   own white-on-dark treatment here, same discipline .els-masthead/
   .spr-header already apply on the public/hub side. */
.ed-header--branded { border-bottom-color: transparent; color: #ffffff; }
.ed-header--branded .ed-header__brand-text strong,
.ed-header--branded .ed-header__brand-text span { color: #ffffff; }
.ed-header--branded .ed-sidebar-toggle,
.ed-header--branded .ed-header__home-link,
.ed-header--branded .ed-bell {
  border-color: rgba(255, 255, 255, 0.35);
  color: #ffffff;
}
.ed-header--branded .ed-sidebar-toggle:hover,
.ed-header--branded .ed-header__home-link:hover,
.ed-header--branded .ed-header__home-link:focus-visible,
.ed-header--branded .ed-bell:hover,
.ed-header--branded .ed-bell:focus-visible {
  border-color: #ffffff;
  color: #ffffff;
}
.ed-header--branded .journal-switcher select {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.35);
  color: #ffffff;
}
.ed-header--branded .theme-toggle { background: rgba(255, 255, 255, 0.14); border-color: rgba(255, 255, 255, 0.3); color: #ffffff; }
.ed-header--branded .theme-toggle:hover { border-color: #ffffff; }
.ed-header--branded .account-menu__toggle { color: #ffffff; }
.ed-header--branded .account-menu__toggle:hover,
.ed-header--branded .account-menu__toggle:focus-visible { border-color: rgba(255, 255, 255, 0.4); background: rgba(255, 255, 255, 0.14); }
.ed-header--branded .account-menu__avatar { background: rgba(255, 255, 255, 0.22); color: #ffffff; }
.ed-header__brand { display: flex; align-items: center; gap: 0.6rem; text-decoration: none; color: inherit; flex: none; }
.ed-header__brand-text { display: flex; flex-direction: column; line-height: 1.2; }
.ed-header__brand-text strong { font-family: var(--font-serif); font-size: 1rem; color: var(--ink); }
.ed-header__brand-text span { font-size: 0.72rem; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.04em; }
.ed-header__brand img { height: 3.2rem; width: auto; max-width: 13rem; object-fit: contain; }
.ed-header__brand svg { width: 22px; height: 22px; stroke: currentColor; flex: none; }
.ed-sidebar-toggle {
  display: none;
  background: none;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  width: 2.1rem;
  height: 2.1rem;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--ink-soft);
  flex: none;
}
.ed-sidebar-toggle svg { width: 18px; height: 18px; stroke: currentColor; }
.ed-header__spacer { flex: 1; }
.ed-header__actions { display: flex; align-items: center; gap: 0.7rem; flex: none; }

/* Same circular-icon-button shape as .ed-bell — a link back out to the
   main VSTE site, not scoped to any one journal. */
.ed-header__home-link { background: none; border: 1px solid var(--border-soft); border-radius: var(--radius-pill); width: 2.3rem; height: 2.3rem; display: inline-grid; place-items: center; color: var(--ink-soft); }
.ed-header__home-link svg { width: 18px; height: 18px; stroke: currentColor; }
.ed-header__home-link:hover, .ed-header__home-link:focus-visible { border-color: var(--accent); color: var(--accent); }

.ed-bell { position: relative; background: none; border: 1px solid var(--border-soft); border-radius: var(--radius-pill); width: 2.3rem; height: 2.3rem; display: inline-grid; place-items: center; cursor: pointer; color: var(--ink-soft); }
.ed-bell svg { width: 18px; height: 18px; stroke: currentColor; }
.ed-bell:hover, .ed-bell:focus-visible { border-color: var(--accent); color: var(--accent); }
.ed-bell__count {
  position: absolute; top: -0.25rem; right: -0.25rem; min-width: 1.1rem; height: 1.1rem; padding: 0 0.25rem;
  border-radius: var(--radius-pill); background: var(--err); color: #fff; font-size: 0.65rem; font-weight: 700;
  display: inline-grid; place-items: center; line-height: 1;
}
.ed-bell__count--hidden { display: none; }
.ed-bell-menu { width: 320px; max-width: 90vw; }
.ed-bell-menu__list { list-style: none; margin: 0; padding: 0.3rem; display: flex; flex-direction: column; gap: 0.15rem; max-height: 22rem; overflow-y: auto; }
.ed-bell-menu__item { display: block; padding: 0.6rem 0.7rem; border-radius: 6px; font-size: 0.85rem; color: var(--ink); text-decoration: none; }
.ed-bell-menu__item:hover { background: var(--bg-soft); }
.ed-bell-menu__item .step__hint { margin: 0.15rem 0 0; }

.ed-account__role { display: block; font-size: 0.7rem; color: var(--ink-faint); font-weight: 400; }

.ed-body { display: flex; flex: 1; min-height: 0; }

.ed-sidebar {
  width: var(--ed-sidebar-width);
  flex: none;
  border-right: 1px solid var(--border-soft);
  background: var(--bg-raised);
  padding: 1.2rem 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  position: sticky;
  top: 56px;
  align-self: flex-start;
  height: calc(100vh - 56px);
  overflow-y: auto;
  transition: margin-left 0.18s var(--ease);
}
.ed-sidebar--collapsed { margin-left: calc(-1 * var(--ed-sidebar-width)); }
.ed-sidebar__group-label { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); margin: 1rem 0.6rem 0.35rem; }
.ed-sidebar__group-label:first-child { margin-top: 0.2rem; }

.ed-nav-item {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.55rem 0.6rem;
  border-radius: var(--radius-sm);
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 0.88rem;
  font-weight: 500;
}
.ed-nav-item svg { flex: none; width: 17px; height: 17px; stroke: currentColor; }
.ed-nav-item:hover { background: var(--bg-soft); color: var(--ink); }
.ed-nav-item--active { background: var(--accent-soft); color: var(--accent-strong); font-weight: 600; }
.ed-nav-item--active:hover { background: var(--accent-soft); }

.ed-sidebar__status {
  margin-top: auto;
  padding-top: 1rem;
  border-top: 1px solid var(--border-soft);
}
.ed-sidebar__status h3 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-faint); margin: 0 0.6rem 0.6rem; }
.ed-sidebar__status-body { padding: 0 0.6rem; font-size: 0.85rem; }
.ed-status-dot { display: inline-flex; align-items: center; gap: 0.4rem; font-weight: 600; margin-bottom: 0.5rem; }
.ed-status-dot::before { content: ""; width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--ink-faint); }
.ed-status-dot--active::before { background: var(--ok); }
.ed-status-dot--draft::before { background: var(--warn); }
.ed-sidebar__status-body dl { margin: 0 0 0.7rem; }
.ed-sidebar__status-body dt { font-size: 0.72rem; color: var(--ink-faint); }
.ed-sidebar__status-body dd { margin: 0 0 0.4rem; font-size: 0.85rem; }
.ed-sidebar__status-body svg { width: 13px; height: 13px; stroke: currentColor; vertical-align: -2px; margin-left: 0.1rem; }

.ed-main { flex: 1; min-width: 0; padding: 2rem 2.5rem 4rem; }

/* Real user request: a breadcrumb trail (Home › Journal › Section) above
   every editorial page's own content, same idea as the public site's own
   .pub-topbar — reuses its .pub-breadcrumb/__sep classes, just wrapped in
   this bar instead (renderEdBreadcrumb, editor.js). */
.ed-breadcrumb { margin-bottom: 1.5rem; }

/* Welcome */
.ed-welcome { display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; margin-bottom: 1.75rem; }
.ed-welcome h1 { font-family: var(--font-serif); font-size: 1.6rem; margin: 0 0 0.2rem; overflow-wrap: anywhere; }
.ed-welcome p { color: var(--ink-soft); margin: 0; }

/* Statistics */
.ed-stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.1rem; margin-bottom: 1.75rem; }
.ed-stat-card {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  background: var(--bg-raised);
  border: 1px solid #e8e8e8;
  border-radius: 14px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.04);
  padding: 1.1rem 1.2rem;
}
.ed-stat-card__icon { flex: none; width: 2.6rem; height: 2.6rem; border-radius: 12px; display: inline-grid; place-items: center; }
.ed-stat-card__icon svg { width: 20px; height: 20px; stroke: currentColor; }
.ed-stat-card__icon--draft { background: var(--ed-pink-bg); color: var(--ed-pink); }
.ed-stat-card__icon--queue { background: var(--warn-bg); color: var(--warn); }
.ed-stat-card__icon--published { background: var(--ok-bg); color: var(--ok); }
.ed-stat-card__icon--upcoming { background: var(--ed-info-bg); color: var(--ed-info); }
.ed-stat-card__count { font-size: 1.55rem; font-weight: 700; line-height: 1.1; font-family: var(--font-serif); }
.ed-stat-card__label { font-size: 0.82rem; color: var(--ink-soft); }
.ed-stat-card__helper { font-size: 0.72rem; color: var(--ink-faint); margin-top: 0.1rem; }

/* Panels grid */
.ed-panels-grid { display: grid; grid-template-columns: 1.6fr 1.1fr 1fr; gap: 1.25rem; align-items: stretch; margin-bottom: 1.75rem; }
.ed-panel {
  display: flex;
  flex-direction: column;
  background: var(--bg-raised);
  border: 1px solid #e8e8e8;
  border-radius: 14px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.04);
  padding: 1.3rem 1.4rem;
}
.ed-panel__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.9rem; }
.ed-panel__head h2 { font-size: 1.02rem; margin: 0; font-family: var(--font-sans); }
.ed-panel__head a { font-size: 0.8rem; color: var(--accent); text-decoration: none; }
.ed-panel__head a:hover { text-decoration: underline; }
.ed-panel__foot { margin-top: 0.9rem; padding-top: 0.8rem; border-top: 1px solid var(--border-soft); text-align: right; }
.ed-panel__foot a { font-size: 0.83rem; color: var(--accent); text-decoration: none; font-weight: 600; }

/* Secondary row: preserved legacy operational alerts + audit trail */
.ed-secondary-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; margin-bottom: 1.75rem; }
.ed-alert-list { margin: 0.3rem 0 0; padding-left: 1.1rem; font-size: 0.83rem; }
.ed-alert-list li { margin-bottom: 0.3rem; }
.ed-alert-list a { color: var(--accent); text-decoration: none; }
.ed-alert-list a:hover { text-decoration: underline; }

.ed-submission-row { display: flex; align-items: flex-start; gap: 0.7rem; padding: 0.65rem 0; border-bottom: 1px solid var(--border-soft); }
.ed-submission-row:last-child { border-bottom: none; }
.ed-submission-row__icon { flex: none; width: 2rem; height: 2rem; border-radius: 8px; background: var(--bg-soft); display: inline-grid; place-items: center; color: var(--ink-soft); }
.ed-submission-row__icon svg { width: 15px; height: 15px; stroke: currentColor; }
.ed-submission-row__body { flex: 1; min-width: 0; }
.ed-submission-row__title { font-size: 0.88rem; font-weight: 600; color: var(--ink); text-decoration: none; display: block; }
.ed-submission-row__title:hover { text-decoration: underline; }
.ed-submission-row__meta { font-size: 0.76rem; color: var(--ink-faint); margin-top: 0.1rem; }
.ed-submission-row > .ed-status-badge { flex: none; margin-top: 0.1rem; }

.ed-status-badge { display: inline-block; padding: 0.2rem 0.6rem; border-radius: var(--radius-pill); font-size: 0.72rem; font-weight: 600; white-space: nowrap; }
.ed-status-badge--draft { background: var(--bg-soft); color: var(--ink-soft); }
.ed-status-badge--new { background: var(--ed-info-bg); color: var(--ed-info); }
.ed-status-badge--review { background: var(--ed-info-bg); color: var(--ed-info); }
.ed-status-badge--queue { background: var(--warn-bg); color: var(--warn); }
.ed-status-badge--revision { background: var(--ed-purple-bg); color: var(--ed-purple); }
.ed-status-badge--accepted { background: var(--ok-bg); color: var(--ok); }
.ed-status-badge--production { background: var(--ed-info-bg); color: var(--ed-info); }
.ed-status-badge--published { background: var(--ok-bg); color: var(--ok); }
.ed-status-badge--critical { background: var(--err-bg); color: var(--err); }

.ed-issue-card { display: flex; gap: 0.8rem; padding: 0.7rem 0; border-bottom: 1px solid var(--border-soft); }
.ed-issue-card:last-child { border-bottom: none; }
.ed-issue-card__cover { flex: none; width: 3rem; height: 4rem; object-fit: cover; border-radius: 6px; background: var(--bg-soft); }
.ed-issue-card__cover--placeholder { display: flex; align-items: center; justify-content: center; color: var(--ink-faint); font-size: 0.7rem; }
.ed-issue-card__body { flex: 1; min-width: 0; }
.ed-issue-card__title { font-size: 0.88rem; font-weight: 600; margin: 0; }
.ed-issue-card__meta { font-size: 0.76rem; color: var(--ink-faint); margin: 0.1rem 0 0.4rem; }
.ed-issue-card__pub { font-size: 0.74rem; color: var(--ink-soft); margin-top: 0.35rem; }

.ed-quick-action {
  display: flex; align-items: center; gap: 0.7rem; padding: 0.6rem 0.5rem; border-radius: var(--radius-sm);
  color: var(--ink); text-decoration: none; font-size: 0.86rem; font-weight: 500;
}
.ed-quick-action:hover { background: var(--bg-soft); }
.ed-quick-action svg { flex: none; width: 16px; height: 16px; stroke: currentColor; color: var(--accent); }
.ed-quick-action__arrow { margin-left: auto; color: var(--ink-faint); }

/* Guidance strip */
.ed-guidance-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.1rem; }
.ed-guidance-card {
  background: var(--bg-raised); border: 1px solid #e8e8e8; border-radius: 14px; box-shadow: 0 4px 18px rgba(0, 0, 0, 0.04);
  padding: 1.2rem 1.3rem; display: flex; flex-direction: column; gap: 0.4rem;
}
.ed-guidance-card__icon { width: 2.1rem; height: 2.1rem; border-radius: 50%; background: var(--accent-soft); color: var(--accent); display: inline-grid; place-items: center; margin-bottom: 0.3rem; }
.ed-guidance-card__icon svg { width: 15px; height: 15px; stroke: currentColor; }
.ed-guidance-card h3 { margin: 0; font-size: 0.95rem; }
.ed-guidance-card p { margin: 0; font-size: 0.82rem; color: var(--ink-soft); }
.ed-guidance-card a { font-size: 0.82rem; color: var(--accent); text-decoration: none; font-weight: 600; }

/* Loading / empty / error states */
.ed-skeleton { background: linear-gradient(100deg, var(--bg-soft) 30%, var(--border-soft) 50%, var(--bg-soft) 70%); background-size: 200% 100%; animation: ed-shimmer 1.3s infinite; border-radius: 8px; }
@keyframes ed-shimmer { to { background-position: -200% 0; } }
.ed-empty-state, .ed-error-state { padding: 1.5rem 0.5rem; text-align: center; color: var(--ink-soft); font-size: 0.86rem; }
.ed-empty-state p, .ed-error-state p { margin: 0 0 0.7rem; }

@media (max-width: 1100px) {
  .ed-panels-grid { grid-template-columns: 1fr 1fr; }
  .ed-panels-grid > :last-child { grid-column: 1 / -1; }
}
@media (max-width: 900px) {
  .ed-sidebar-toggle { display: inline-flex; }
  .ed-sidebar { position: fixed; left: 0; top: 56px; z-index: 39; box-shadow: var(--shadow-lg); margin-left: calc(-1 * var(--ed-sidebar-width)); }
  .ed-sidebar--open { margin-left: 0; }
  .ed-stats-grid { grid-template-columns: 1fr 1fr; }
  .ed-panels-grid { grid-template-columns: 1fr; }
  .ed-secondary-grid { grid-template-columns: 1fr; }
  .ed-guidance-grid { grid-template-columns: 1fr; }
  .ed-main { padding: 1.5rem 1.25rem 3rem; }
  /* .ed-header__brand and .ed-header__actions are both flex: none by
     design (neither should get squeezed illegibly thin) — on a narrow
     viewport that means the *other* variable-width pieces (the journal
     switcher, the account label) have to be the ones that give, or the
     row as a whole silently overflows past the viewport with no way to
     scroll to the clipped part (body has overflow-x: hidden). */
  #journal-switcher select { max-width: 7rem; }
  .account-menu__label { max-width: 7rem; }
}
@media (max-width: 560px) {
  .ed-stats-grid { grid-template-columns: 1fr; }
  .ed-welcome { flex-direction: column; align-items: flex-start; }
  /* Below ~560px there still isn't room for brand text + switcher +
     account label all at once — the logo mark alone (still a link home)
     plus the hamburger stays the identity anchor; full names/emails are
     one tap away in the account menu itself. */
  .ed-header { gap: 0.3rem; padding: 0.65rem 0.6rem; }
  .ed-header__brand-text { display: none; }
  #journal-switcher select { max-width: 4.5rem; }
  .account-menu__label { display: none; }
}
