/* Compass — Bullet Journal aesthetic
   Cream paper, ink blue, rust accents, serif body, mono for tech labels.
   Mobile-first. Light by default, dark = midnight-ink mode (toggle in header). */

:root {
    --paper:    #F4F1E8;
    --paper-2:  #ECE7D9;
    --paper-3:  #E2DCCA;
    --ink:      #1F3D7A;
    --ink-2:    #2B2B2B;
    --ink-3:    #4A4A4A;
    --rust:     #A04528;
    --muted:    #7A7468;
    --rule:     rgba(31, 61, 122, 0.18);
    --ok:       #5C8A3A;
    --danger:   #B23A3A;
    --warn:     #C77A1F;

    --serif:  "Iowan Old Style", "Source Serif 4", "Source Serif Pro",
              Charter, "Palatino Linotype", Georgia, serif;
    --mono:   "JetBrains Mono", "SF Mono", "IBM Plex Mono",
              Menlo, Consolas, ui-monospace, monospace;
    --radius: 4px;
}

/* Dark mode = "midnight ink" — same paper-and-ink language, after dusk.
   Cream becomes the foreground, deep navy becomes the page. Rust glows. */
:root.dark {
    --paper:    #14181F;
    --paper-2:  #1C2230;
    --paper-3:  #262E40;
    --ink:      #E8E2D0;
    --ink-2:    #F0EBD9;
    --ink-3:    #C4C0B0;
    --rust:     #E89668;
    --muted:    #8E8674;
    --rule:     rgba(232, 226, 208, 0.18);
    --ok:       #8DBC6A;
    --danger:   #E27575;
    --warn:     #E5B36A;
}
:root.dark body {
    background-image:
      radial-gradient(circle at 20% 10%, rgba(232, 226, 208, 0.04) 0, transparent 45%),
      radial-gradient(circle at 80% 70%, rgba(232, 226, 208, 0.05) 0, transparent 55%);
}

* { box-sizing: border-box; }
html { -webkit-font-smoothing: antialiased; }

body {
    margin: 0;
    background: var(--paper);
    color: var(--ink-2);
    font-family: var(--serif);
    line-height: 1.55;
    /* Subtle paper grain — soft radial warmth, no rule lines */
    background-image:
      radial-gradient(circle at 20% 10%, rgba(0,0,0,0.018) 0, transparent 45%),
      radial-gradient(circle at 80% 70%, rgba(0,0,0,0.022) 0, transparent 55%);
    -webkit-tap-highlight-color: transparent;
}

/* ---- Header / masthead ---- */

body > header {
    padding: 18px 24px;
    border-bottom: 1.5px solid var(--ink);
    background: var(--paper);
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

.logo {
    font-family: var(--serif);
    font-style: italic;
    font-weight: 700;
    font-size: 26px;
    color: var(--ink);
    text-decoration: none;
    letter-spacing: -0.01em;
    line-height: 1;
}
.logo em { font-style: italic; font-weight: 700; }
.logo .dot { color: var(--rust); font-weight: 900; font-style: normal; }

/* Right-aligned actions group (theme toggle + logout when signed in). */
.header-actions { display: flex; gap: 8px; margin-left: auto; }
.logout-form { margin: 0; display: inline; }

/* Inline form error on login/signup pages. */
.error-message {
    background: var(--paper-2);
    border-left: 3px solid var(--rust);
    color: var(--rust);
    padding: 10px 14px;
    margin: 12px 0;
    font-size: 14px;
}

/* Theme toggle: small mono pill on the right of the masthead. */
.theme-toggle {
    background: transparent;
    color: var(--ink);
    border: 1px solid var(--ink);
    padding: 5px 12px;
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    cursor: pointer;
    border-radius: 2px;
    box-shadow: none;
    align-self: center;
    transition: background 0.12s, color 0.12s;
}
.theme-toggle:hover {
    background: var(--ink);
    color: var(--paper);
    transform: none;
    box-shadow: none;
}
.theme-toggle:active { transform: none; box-shadow: none; }

/* Sync status pill: tiny, quiet — a colored dot + word. Click to sync now. */
.sync-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: transparent;
    color: var(--muted);
    border: 1px solid var(--rule);
    padding: 5px 10px;
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    cursor: pointer;
    border-radius: 999px;
    align-self: center;
    transition: background 0.12s, border-color 0.12s;
}
.sync-status:hover { background: var(--paper-2); }
.sync-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--muted);
    flex: none;
}
.sync-status[data-state="synced"]  .sync-dot { background: var(--ok); }
.sync-status[data-state="pending"] .sync-dot { background: var(--warn); }
.sync-status[data-state="offline"] .sync-dot { background: var(--muted); }
.sync-status[data-state="syncing"] .sync-dot {
    background: var(--ink);
    animation: sync-pulse 1s ease-in-out infinite;
}
@keyframes sync-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) {
    .sync-status[data-state="syncing"] .sync-dot { animation: none; }
}
/* On phones, drop the word and keep just the dot to save header width; the
   color (+ tap to sync) still conveys state. Hidden entirely on very narrow
   screens where even the dot won't fit beside the nav + actions. */
@media (max-width: 600px) {
    .sync-status { padding: 6px; }
    .sync-label { display: none; }
}
@media (max-width: 360px) {
    .sync-status { display: none; }
}

main {
    margin: 0 auto;
    padding: 40px 24px 100px;
}

/* ---- Headings ---- */

h1 {
    font-family: var(--serif);
    margin: 0 0 18px;
    font-size: 28px;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--ink-2);
    line-height: 1.2;
}
h1 .subtle {
    color: var(--muted);
    font-weight: 400;
    font-style: italic;
    font-size: 19px;
    margin-left: 8px;
}

h2 {
    display: inline-block;
    margin: 36px 0 18px;
    padding-bottom: 4px;
    font-family: var(--serif);
    font-size: 13px;
    font-weight: 700;
    color: var(--ink);
    text-transform: uppercase;
    letter-spacing: 0.16em;
    background-image: linear-gradient(transparent calc(100% - 2px),
                                       var(--rust) calc(100% - 2px));
    background-repeat: no-repeat;
    background-size: 100% 100%;
}

h3 {
    margin: 22px 0 10px;
    font-family: var(--serif);
    font-size: 16px;
    font-weight: 700;
    color: var(--ink-2);
    font-style: italic;
}

/* ---- Inline elements ---- */

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

.subtle, .hint { color: var(--muted); }
.subtle { font-style: italic; font-size: 15px; }

.empty {
    color: var(--muted);
    font-style: italic;
    font-size: 14px;
}

.back {
    display: inline-block;
    color: var(--ink);
    text-decoration: none;
    margin-bottom: 14px;
    font-size: 14px;
    font-style: italic;
    border-bottom: 1px solid transparent;
}
.back:hover { border-bottom-color: var(--rust); color: var(--rust); }

code {
    font-family: var(--mono);
    background: var(--paper-2);
    padding: 1px 6px;
    border-radius: 2px;
    font-size: 12px;
    color: var(--ink);
}

/* ---- Lists (shared reset) ---- */

.class-list, .policy-list, .event-list, .doc-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* ---- Upload card (now positioned below the classes list) ---- */

.upload-card {
    margin: 8px 0 0;
    padding: 0;
    display: block;
}
.upload-card > h2 { margin-top: 36px; }
.upload-card > p.subtle { margin: 0 0 20px; font-size: 15px; }
.upload-card form { margin-top: 0; }

/* Center the primary upload button under the drop zone. */
.upload-card .actions {
    margin-top: 18px;
    display: flex;
    justify-content: center;
}
.upload-card .actions button {
    align-self: center;
}

/* ---- Drop zone ---- */

.drop-zone {
    position: relative;
    padding: 44px 24px;
    border: 2px dashed var(--ink);
    border-radius: var(--radius);
    background: var(--paper);
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease, transform 0.05s ease;
    margin-bottom: 14px;
    text-align: center;
    overflow: hidden;
}
/* Pinned dots in opposite corners — hand-drawn paper feel */
.drop-zone::before, .drop-zone::after {
    content: "";
    position: absolute;
    width: 12px; height: 12px;
    border: 1.5px solid var(--ink);
    border-radius: 50%;
    background: var(--paper);
    z-index: 3;
    pointer-events: none;
}
.drop-zone::before { top: -7px; left: -7px; }
.drop-zone::after  { bottom: -7px; right: -7px; }
.drop-zone:hover { background: var(--paper-2); border-color: var(--rust); }
.drop-zone.drag {
    background: var(--paper-2);
    border-color: var(--rust);
    transform: scale(1.005);
}
.drop-zone.reject {
    border-color: var(--danger);
    animation: dropShake 0.4s;
}
.drop-zone.has-file {
    padding: 18px 22px;
    border-style: solid;
    background: var(--paper-2);
    border-color: var(--ink);
}
.drop-zone.has-file::before, .drop-zone.has-file::after {
    border-color: var(--rust);
}

@keyframes dropShake {
    0%, 100% { transform: translateX(0); }
    20% { transform: translateX(-5px); }
    60% { transform: translateX(5px); }
    80% { transform: translateX(-2px); }
}

.drop-zone input[type="file"] {
    position: absolute;
    inset: 0;
    width: 100%; height: 100%;
    opacity: 0;
    cursor: pointer;
    z-index: 1;
}

.drop-prompt { pointer-events: none; }
.drop-zone.has-file .drop-prompt { display: none; }

.drop-line {
    font-family: var(--serif);
    font-size: 18px;
    font-style: italic;
    color: var(--ink-2);
    margin: 0 0 6px;
}
/* Mockup-style two-action prompt: "Drop a PDF here  or  choose a file" */
.drop-prompt .drop-line .or {
    color: var(--muted);
    font-style: normal;
    font-size: 13px;
    margin: 0 8px;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-family: var(--mono);
}
.drop-prompt .drop-line .underline {
    color: var(--ink);
    font-weight: 700;
    font-style: italic;
    text-decoration: underline;
    text-decoration-color: var(--rust);
    text-underline-offset: 3px;
    text-decoration-thickness: 2px;
}

.drop-glyph {
    font-family: var(--mono);
    font-size: 24px;
    color: var(--ink);
    letter-spacing: 0.4em;
    margin-bottom: 12px;
    user-select: none;
    pointer-events: none;
}

.drop-hint {
    margin-top: 12px;
    font-family: var(--mono);
    font-size: 11px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.18em;
}

.drop-picked {
    display: none;
    align-items: center;
    gap: 12px;
    text-align: left;
    position: relative;
    z-index: 2;
}
.drop-zone.has-file .drop-picked { display: flex; }
.drop-picked .name {
    flex: 1 1 auto;
    font-family: var(--serif);
    font-weight: 600;
    color: var(--ink-2);
    word-break: break-all;
    font-size: 15px;
}
.drop-picked .size {
    font-family: var(--mono);
    color: var(--muted);
    font-size: 11px;
    flex-shrink: 0;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.drop-picked .clear-file {
    flex-shrink: 0;
    padding: 4px 10px;
    font-family: var(--mono);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    background: transparent;
    color: var(--muted);
    border: 1px solid var(--ink);
    border-radius: 2px;
    cursor: pointer;
    box-shadow: none;
}
.drop-picked .clear-file:hover {
    color: var(--rust);
    border-color: var(--rust);
    background: var(--paper);
}

/* ---- Class list (ledger style) ---- */

.class-card {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: baseline;
    gap: 14px;
    padding: 14px 18px;
    background: var(--paper-2);
    border-left: 3px solid var(--ink);
    border-radius: 2px;
    box-shadow: 0 1px 0 rgba(0,0,0,0.04);
    text-decoration: none;
    color: inherit;
    transition: transform 0.12s ease, border-color 0.12s ease;
}
.class-list li:nth-child(odd)  .class-card { transform: rotate(-0.12deg); }
.class-list li:nth-child(even) .class-card { transform: rotate(0.08deg); }
.class-card:hover {
    transform: translateX(2px) rotate(0deg);
    border-left-color: var(--rust);
    background: var(--paper-3);
}
.class-card .code {
    font-family: var(--serif);
    font-weight: 700;
    color: var(--ink);
    font-size: 16px;
    letter-spacing: -0.01em;
    min-width: 92px;
}
.class-card .name {
    font-family: var(--serif);
    font-style: italic;
    font-size: 16px;
    color: var(--ink-2);
}

/* ---- Policy list ---- */

.policy-list li {
    padding: 14px 18px;
    background: var(--paper-2);
    border-left: 3px solid var(--ink);
    border-radius: 2px;
}
.policy-list li strong {
    display: block;
    font-family: var(--mono);
    font-size: 11px;
    color: var(--rust);
    text-transform: uppercase;
    letter-spacing: 0.16em;
    margin-bottom: 8px;
    font-weight: 700;
}
.policy-list li p { margin: 0; font-family: var(--serif); }

.policy-list table.grading {
    border-collapse: collapse;
    margin-top: 4px;
    width: 100%;
    max-width: 360px;
}
.policy-list table.grading td {
    padding: 6px 12px 6px 0;
    font-family: var(--serif);
    font-size: 15px;
    border-bottom: 1px dotted var(--rule);
}
.policy-list table.grading td:last-child {
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    text-align: right;
    font-family: var(--mono);
    font-size: 13px;
}
.policy-list table.grading tr:last-child td { border-bottom: none; }

.policy-list ul.oh {
    margin: 4px 0 0;
    padding-left: 20px;
    font-family: var(--serif);
    font-size: 15px;
    color: var(--ink-2);
}
.policy-list ul.oh li { padding: 2px 0; background: transparent; border: none; border-radius: 0; }

/* ---- Events ---- */

.event-list li {
    padding: 12px 18px;
    background: var(--paper-2);
    border-left: 3px solid var(--ink);
    border-radius: 2px;
    display: grid;
    grid-template-columns: 90px 1fr auto auto;
    gap: 14px;
    align-items: baseline;
}
.event-list .event-add-cal-form {
    margin: 0;
    padding: 0;
}
.event-list .event-add-cal {
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 700;
    color: var(--rust);
    background: transparent;
    border: 1px solid var(--rust);
    padding: 3px 8px;
    border-radius: 2px;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    white-space: nowrap;
    cursor: pointer;
    transition: background 0.1s, color 0.1s;
    box-shadow: none;
}
.event-list .event-add-cal:hover {
    background: var(--rust);
    color: var(--paper);
    transform: none;
    box-shadow: none;
}
.event-list .kind {
    font-family: var(--mono);
    font-size: 10px;
    text-transform: uppercase;
    color: var(--rust);
    letter-spacing: 0.14em;
    font-weight: 700;
}
.event-list .title {
    font-family: var(--serif);
    font-weight: 500;
    font-size: 15px;
    color: var(--ink-2);
}
.event-list .when {
    font-family: var(--mono);
    font-size: 12px;
    color: var(--ink);
    white-space: nowrap;
    font-style: normal;
}
.event-list .row-actions {
    grid-column: 1 / -1;
    margin-top: 4px;
}

/* Per-event "Add / Remove from calendar" toggle buttons.
   Shape mirrors the legacy .event-add-cal; color signals direction —
   rust for "add", muted ink for "remove". */
.event-list .event-cal-toggle-form {
    margin: 0;
    padding: 0;
}
.event-list .event-cal-add,
.event-list .event-cal-remove {
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 700;
    background: transparent;
    padding: 3px 8px;
    border-radius: 2px;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    white-space: nowrap;
    cursor: pointer;
    transition: background 0.1s, color 0.1s;
    box-shadow: none;
}
.event-list .event-cal-add {
    color: var(--rust);
    border: 1px solid var(--rust);
}
.event-list .event-cal-add:hover {
    background: var(--rust);
    color: var(--paper);
    transform: none;
    box-shadow: none;
}
.event-list .event-cal-remove {
    color: var(--ink);
    border: 1px solid var(--ink-2, var(--ink));
    opacity: 0.7;
}
.event-list .event-cal-remove:hover {
    background: var(--ink);
    color: var(--paper);
    opacity: 1;
    transform: none;
    box-shadow: none;
}

/* Post-parse "we found N events" callout. Set apart from the rest of
   the Events section so it draws the eye on first land — but not so
   loud that it's a permanent fixture (it disappears once everything's
   added or removed). */
.events-review-banner {
    margin: 0 0 18px;
    padding: 16px 18px;
    background: var(--paper-2);
    border: 1px solid var(--rust);
    border-left: 4px solid var(--rust);
    border-radius: 2px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.events-review-banner-text {
    font-family: var(--serif);
    font-size: 15px;
    color: var(--ink-2, var(--ink));
}
.events-review-banner-text strong {
    color: var(--rust);
    font-weight: 700;
}
.events-review-banner-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
}
.events-review-banner-actions .subtle {
    font-size: 12px;
    font-family: var(--mono);
}

/* Pending review / On calendar subsection headers + their bulk-action
   button. The h3 keeps a narrow visual weight so it doesn't compete
   with the section h2. */
.events-subsection {
    margin-top: 18px;
}
.events-subsection:first-child {
    margin-top: 0;
}
.events-subsection-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 8px;
}
.events-subsection-head h3 {
    margin: 0;
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--ink);
}
.events-subsection-head form.inline {
    margin: 0;
}

/* Top-of-section toolbar — surfaces destructive bulk actions (Delete
   all events) when no review banner is present. When the banner IS
   present, Delete all lives inside .events-review-banner-actions
   alongside Add all so the user doesn't have to scroll. */
.events-section-toolbar {
    display: flex;
    justify-content: flex-end;
    margin: 0 0 12px;
}
.events-section-toolbar form.inline { margin: 0; }

@media (max-width: 480px) {
    .event-list .event-cal-add,
    .event-list .event-cal-remove { grid-column: 1 / -1; justify-self: start; }
    .events-review-banner-actions { flex-direction: column; align-items: flex-start; }
    .events-subsection-head { flex-direction: column; align-items: flex-start; }
}

/* ---- Syllabus link section (top of class page) ---- */

.syllabus-link {
    margin-top: 8px;
}
.syllabus-link p {
    margin: 0 0 8px;
    font-family: var(--serif);
}
.syllabus-link a {
    color: var(--ink);
    text-decoration: underline;
    text-decoration-color: var(--rust);
    text-underline-offset: 3px;
    text-decoration-thickness: 2px;
    font-weight: 600;
    font-style: italic;
}
.syllabus-link a:hover { color: var(--rust); }
.syllabus-link p.hint {
    font-family: var(--mono);
    font-size: 11px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    margin-top: 6px;
}

/* ---- Source-quote disclosure (verifying Grok's extractions) ---- */

details.source {
    margin-top: 6px;
}
details.source summary {
    cursor: pointer;
    font-family: var(--mono);
    font-size: 10px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    list-style: none;
    display: inline-block;
}
details.source summary::-webkit-details-marker { display: none; }
details.source summary::before { content: "▸ "; color: var(--rust); }
details.source[open] summary::before { content: "▾ "; }
details.source summary:hover { color: var(--rust); }
details.source blockquote {
    margin: 6px 0 0;
    padding: 8px 12px;
    border-left: 2px solid var(--rust);
    background: var(--paper);
    font-family: var(--serif);
    font-style: italic;
    font-size: 13px;
    color: var(--ink-3);
    line-height: 1.45;
}
details.source.inline {
    display: inline-block;
    margin-left: 8px;
}
details.source.event-source {
    grid-column: 1 / -1;
    margin-top: 4px;
}

.policy-list table.grading td.source-cell {
    width: auto;
    text-align: left;
    font-weight: normal;
    font-family: var(--serif);
    font-size: 13px;
    padding-left: 12px;
}
.policy-list table.grading td.source-cell details.source {
    margin-top: 0;
}

/* ---- Inline edit (collapsible) ---- */

.row-actions summary {
    cursor: pointer;
    font-family: var(--mono);
    font-size: 11px;
    color: var(--ink);
    list-style: none;
    margin-top: 6px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.row-actions summary::-webkit-details-marker { display: none; }
.row-actions summary::before { content: "edit "; opacity: 0.6; }
.row-actions[open] summary::before { content: "close "; }
.row-actions summary:hover { color: var(--rust); }

.inline-edit {
    margin-top: 12px;
    padding: 12px;
    background: var(--paper);
    border-radius: 2px;
    border: 1px dashed var(--rule);
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.inline-edit label {
    font-family: var(--mono);
    font-size: 11px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.inline-edit textarea, .inline-edit input, .inline-edit select {
    padding: 8px 10px;
    font-size: 14px;
    font-family: var(--serif);
    background: var(--paper);
    color: var(--ink-2);
    border: 1px solid var(--rule);
    border-radius: 2px;
}

/* ---- Documents ---- */

.doc-list li {
    padding: 12px 18px;
    background: var(--paper-2);
    border-left: 3px solid var(--ink);
    border-radius: 2px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.doc-list a {
    color: var(--ink);
    text-decoration: underline;
    text-decoration-color: var(--rust);
    text-underline-offset: 3px;
    text-decoration-thickness: 1.5px;
    flex: 1;
    font-family: var(--serif);
    font-size: 15px;
}
.doc-list .inline { display: inline; margin: 0; }

/* ---- Forms (general) ---- */

form {
    margin-top: 24px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

form.add-class, form.add-doc {
    background: var(--paper-2);
    padding: 20px;
    border-radius: var(--radius);
    border-left: 3px solid var(--ink);
    margin-top: 16px;
}
form.add-class h3, form.add-doc h3 { margin: 0 0 8px; }

/* Syllabus actions row (Reparse + Delete PDF) sit side by side, each with
   its button over an explanatory line; wrap to a column on narrow screens. */
.syllabus-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 28px;
    margin-top: 20px;
}
.syllabus-actions form { margin-top: 0; gap: 6px; }

label {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-family: var(--mono);
    font-size: 11px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

input[type="text"], input[type="password"], select, textarea {
    padding: 12px 14px;
    border: 1px solid var(--rule);
    border-radius: 2px;
    background: var(--paper);
    color: var(--ink-2);
    font-size: 16px;
    font-family: var(--serif);
}
input:focus, select:focus, textarea:focus {
    outline: 2px solid var(--ink);
    outline-offset: -1px;
    /* Keep theme-driven background so dark mode stays dark on focus —
       the ink-colored outline alone is enough focus indication. */
}

textarea { resize: vertical; min-height: 60px; }

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

button {
    appearance: none;
    background: var(--ink);
    color: var(--paper);
    border: none;
    padding: 12px 28px;
    font-family: var(--serif);
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    border-radius: 2px;
    box-shadow: 2px 2px 0 var(--rust);
    transition: transform 0.08s, box-shadow 0.08s;
    align-self: flex-start;
}
button:hover  { transform: translate(-1px, -1px); box-shadow: 3px 3px 0 var(--rust); }
button:active { transform: translate(1px, 1px); box-shadow: 1px 1px 0 var(--rust); }

button.danger-btn {
    background: var(--paper);
    color: var(--danger);
    border: 1px solid var(--danger);
    padding: 8px 14px;
    font-size: 13px;
    box-shadow: 2px 2px 0 var(--rust);
}
button.danger-btn:hover {
    background: var(--danger);
    color: var(--paper);
}
button.danger-btn.small {
    padding: 4px 10px;
    font-size: 12px;
    line-height: 1;
}

form.danger { margin-top: 56px; }
form.danger button {
    background: var(--paper);
    color: var(--danger);
    border: 1px solid var(--danger);
    box-shadow: 2px 2px 0 var(--rust);
}
form.danger button:hover {
    background: var(--danger);
    color: var(--paper);
}

/* ---- Manual add (collapsed by default) ---- */

.manual-add {
    margin-top: 36px;
    padding: 14px 18px;
    background: var(--paper-2);
    border-radius: var(--radius);
    border-left: 3px solid var(--rule);
}
.manual-add summary {
    cursor: pointer;
    font-family: var(--mono);
    font-size: 12px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    list-style: none;
}
.manual-add summary::-webkit-details-marker { display: none; }
.manual-add summary::before { content: "+ "; color: var(--ink); font-weight: 700; }
.manual-add[open] summary::before { content: "− "; }
.manual-add summary:hover { color: var(--ink); }

/* ---- Status / spinner (parsing page) ---- */

.status-card {
    background: var(--paper-2);
    padding: 36px 26px;
    border-radius: var(--radius);
    margin-top: 32px;
    text-align: center;
    border-left: 3px solid var(--ink);
}
.status-card h1 {
    margin: 0 0 8px;
    font-style: italic;
    font-weight: 600;
}
.status-card.error {
    border-left-color: var(--danger);
    background: color-mix(in srgb, var(--danger) 8%, var(--paper-2));
}
.status-card .hint {
    font-family: var(--mono);
    font-size: 11px;
    margin-top: 8px;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--muted);
}
.spinner {
    width: 32px; height: 32px;
    margin: 24px auto 0;
    border: 3px solid var(--paper-3);
    border-top-color: var(--rust);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

a.primary-link.disabled {
    color: var(--muted);
    text-decoration-color: var(--rule);
    pointer-events: none;
    cursor: wait;
    opacity: 0.7;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- Setup token card ---- */

.setup-card {
    background: var(--paper-2);
    padding: 28px 24px;
    border-radius: var(--radius);
    margin-top: 32px;
    border-left: 3px solid var(--ink);
}
.setup-card h1 { margin: 0 0 12px; font-size: 22px; font-style: italic; }
.setup-card p  { margin: 0 0 18px; }
.setup-card code { background: var(--paper); }
.primary-link {
    display: inline-block;
    color: var(--ink);
    text-decoration: underline;
    text-decoration-color: var(--rust);
    text-underline-offset: 3px;
    text-decoration-thickness: 2px;
    font-weight: 600;
    font-family: var(--serif);
    font-style: italic;
}

/* ---- Footer / colophon ---- */

.cal-link {
    margin-top: 64px;
    padding-top: 18px;
    border-top: 1px solid var(--rule);
    font-family: var(--serif);
    font-style: italic;
    font-size: 13px;
    color: var(--muted);
    text-align: center;
}
.cal-link code {
    background: var(--paper-2);
    font-style: normal;
    font-size: 12px;
}

/* ---- Cards (user-curated highlights) ---- */

.card-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.card-item {
    padding: 0;
    background: var(--paper-2);
    border-left: 3px solid var(--ink);
    border-radius: 2px;
    overflow: hidden;
    display: flex;
    align-items: stretch;
    transition: opacity 0.12s ease, transform 0.12s ease, box-shadow 0.12s ease;
    /* Top/bottom borders for drag drop indicators (default invisible) */
    border-top: 3px solid transparent;
    border-bottom: 3px solid transparent;
}
.card-item--summary { border-left-color: var(--rust); }
.card-item--tailor  { border-left-color: var(--rust); }

/* ---- Burger drag handle (left side of every card) ---- */

.card-drag-handle {
    flex-shrink: 0;
    width: 36px;
    background: transparent;
    cursor: grab;
    display: flex;
    align-items: center;
    justify-content: center;
    user-select: none;
    -webkit-user-select: none;
    transition: background 0.1s ease;
    /* Force the browser to treat this as a draggable block; some browsers
       quirk on inline draggables. */
    touch-action: none;
}
.card-drag-handle:hover { background: rgba(0, 0, 0, 0.04); }
.card-drag-handle:active { cursor: grabbing; }
:root.dark .card-drag-handle:hover { background: rgba(255, 255, 255, 0.04); }

.burger-icon {
    width: 18px;
    height: 12px;
    background-image: linear-gradient(to bottom,
        var(--ink) 0, var(--ink) 2px,
        transparent 2px, transparent 5px,
        var(--ink) 5px, var(--ink) 7px,
        transparent 7px, transparent 10px,
        var(--ink) 10px, var(--ink) 12px);
}

/* The card-details should fill the remaining space next to the handle. */
.card-item > details.card-details {
    flex: 1;
    min-width: 0;
}

/* Drag visual: card lifts off the page — solid (not translucent), slight
   scale-up, dramatic shadow. The scale is also applied via inline transform
   in JS so it survives the FLIP animation. */
.card-item.dragging {
    opacity: 1;
    z-index: 5;
    box-shadow: 0 14px 30px rgba(0, 0, 0, 0.22), 0 4px 8px rgba(0, 0, 0, 0.12);
    cursor: grabbing;
}
:root.dark .card-item.dragging {
    box-shadow: 0 14px 30px rgba(0, 0, 0, 0.55), 0 4px 8px rgba(0, 0, 0, 0.35);
}
.card-item.drop-above {
    border-top-color: var(--rust);
}
.card-item.drop-below {
    border-bottom-color: var(--rust);
}

/* While a drag is in progress, suppress text selection and tap highlight
   everywhere on the page so the cursor doesn't accidentally start selecting
   text mid-drag. */
body.cards-dragging,
body.cards-dragging * {
    user-select: none !important;
    -webkit-user-select: none !important;
    cursor: grabbing !important;
}

/* ---- Card-level details (outer collapse) ---- */

details.card-details > summary.card-summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 18px 12px;
    border-bottom: 1.5px solid var(--ink);
    background: var(--paper-2);
    transition: background 0.1s;
}
details.card-details > summary.card-summary::-webkit-details-marker { display: none; }
details.card-details > summary.card-summary::marker { content: ''; }
details.card-details > summary.card-summary:hover { background: var(--paper-3); }

.card-summary-text {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}
.card-kind {
    font-family: var(--mono);
    font-size: 10px;
    color: var(--rust);
    text-transform: uppercase;
    letter-spacing: 0.16em;
    font-weight: 700;
}
.card-title {
    font-family: var(--serif);
    font-weight: 700;
    color: var(--ink);
    font-size: 19px;
    line-height: 1.25;
    letter-spacing: -0.005em;
    word-wrap: break-word;
}
.card-tailor-prompt {
    font-family: var(--serif);
    font-style: italic;
    font-size: 13px;
    color: var(--muted);
    line-height: 1.4;
}
.card-tailor-prompt-label {
    font-family: var(--mono);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--rust);
    font-style: normal;
    margin-right: 4px;
}

/* Card-summary right-side controls cluster (Delete + chevron). */
.card-summary-controls {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-shrink: 0;
}

/* Big "Delete" button on the card title row. Always visible — primary path
   for getting rid of a card. Inside <summary>, so its click handler must
   stop propagation to avoid toggling the disclosure. */
.card-delete-btn {
    background: var(--paper);
    color: var(--danger);
    border: 1.5px solid var(--danger);
    padding: 8px 18px;
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    cursor: pointer;
    border-radius: 2px;
    box-shadow: 2px 2px 0 var(--rust);
    align-self: auto;
    transition: background 0.1s, color 0.1s, transform 0.05s, box-shadow 0.05s;
}
.card-delete-btn:hover {
    background: var(--danger);
    color: var(--paper);
    transform: translate(-1px, -1px);
    box-shadow: 3px 3px 0 var(--rust);
}
.card-delete-btn:active {
    transform: translate(1px, 1px);
    box-shadow: 1px 1px 0 var(--rust);
}

/* Custom chevron — rotates with state. */
.card-toggle-chevron,
.section-toggle-chevron {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    margin-top: 4px;
    background: none;
    position: relative;
    transition: transform 0.15s ease;
}
.card-toggle-chevron::before,
.section-toggle-chevron::before {
    content: '';
    position: absolute;
    top: 4px;
    left: 4px;
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--ink);
    border-bottom: 2px solid var(--ink);
    transform: rotate(45deg);
    transition: transform 0.15s ease;
}
details:not([open]) > summary .card-toggle-chevron::before,
details:not([open]) > summary .section-toggle-chevron::before {
    transform: rotate(-45deg);
    top: 6px;
}

.card-content {
    padding: 14px 18px;
}

/* ---- Per-section details (inner collapses) ---- */

details.section-details {
    margin-bottom: 14px;
}
details.section-details:last-of-type { margin-bottom: 0; }
details.section-details > summary.section-summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 4px 0;
    margin-bottom: 6px;
}
details.section-details > summary.section-summary::-webkit-details-marker { display: none; }
details.section-details > summary.section-summary::marker { content: ''; }

.section-summary-text {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    min-width: 0;
}
.section-title {
    font-family: var(--serif);
    font-weight: 700;
    color: var(--ink);
    font-size: 15px;
    line-height: 1.3;
    /* The line under the section heading, only as wide as the text. */
    border-bottom: 1.5px solid var(--rust);
    padding-bottom: 2px;
    display: inline-block;
}
.section-title--unnamed {
    color: var(--muted);
    font-style: italic;
    font-weight: 600;
}

/* Per-section kind badge (summary / verbatim) shown next to the section title. */
.section-kind {
    font-family: var(--mono);
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    padding: 2px 7px;
    border-radius: 10px;
    display: inline-block;
    line-height: 1.3;
    border: 1px solid transparent;
}
.section-kind--tailor {
    background: var(--rust);
    color: var(--paper);
}
/* Old summary-class fallback for any cards still labeled "summary" in the DOM. */
.section-kind--summary {
    background: var(--rust);
    color: var(--paper);
}
.section-kind--verbatim {
    background: var(--paper);
    color: var(--ink);
    border-color: var(--ink);
}
.single-section-kind {
    margin: 0 0 10px;
}
.section-content {
    /* Shifted slightly to make the content visually nested under the section title. */
    padding-left: 2px;
}

.card-body {
    margin: 0;
    font-family: var(--serif);
    font-size: 15px;
    color: var(--ink-2);
    line-height: 1.55;
}

/* ---- Section picker (two-column on desktop, stacked on mobile) ---- */

.sections-page {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: 28px;
    align-items: start;
    margin-top: 8px;
    /* Break out of the 720px main width so the side panel has room */
    width: min(1100px, calc(100vw - 48px));
    margin-left: calc(-1 * (min(1100px, calc(100vw - 48px)) - 100%) / 2);
}
.sections-page > .hint {
    grid-column: 1 / -1;
    font-family: var(--serif);
    font-style: italic;
    font-size: 14px;
    color: var(--muted);
    margin: 0 0 8px;
    line-height: 1.55;
}
.sections-page > .hint strong {
    color: var(--ink);
    font-style: normal;
    font-weight: 700;
    background: var(--paper-2);
    padding: 1px 6px;
    border-radius: 2px;
    font-family: var(--mono);
    font-size: 12px;
}

.sections-text {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.section-article {
    background: var(--paper-2);
    border-left: 3px solid var(--rule);
    border-radius: 2px;
    padding: 14px 18px;
    transition: border-color 0.1s, background 0.1s;
}
.section-article--lvl2 {
    margin-left: 20px;
    background: var(--paper);
    border-left-color: var(--rule);
}
.section-article--lvl3 {
    margin-left: 40px;
    background: var(--paper);
}
.section-article:hover { border-left-color: var(--ink); }
.section-article.picked { border-left-color: var(--ink); background: var(--paper-3); }
.section-article.active-group {
    box-shadow: inset 0 0 0 1px var(--ink);
}

.section-article-head {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 8px;
    flex-wrap: wrap;
}
.section-article-heading {
    flex: 1 1 200px;
    margin: 0;
    font-family: var(--serif);
    font-weight: 700;
    color: var(--ink);
    font-size: 18px;
    line-height: 1.3;
    min-width: 0;
}
.section-article--lvl2 .section-article-heading { font-size: 16px; font-style: italic; }
.section-article--lvl3 .section-article-heading {
    font-size: 14px;
    font-style: italic;
    color: var(--ink-2);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.section-marker {
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 1.5px solid var(--rule);
    background: var(--paper);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 700;
    color: white;
    line-height: 1;
    margin-top: 2px;
}

.section-article-actions {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
}
.add-btn {
    background: var(--paper);
    color: var(--ink);
    border: 1px solid var(--ink);
    padding: 5px 12px;
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    cursor: pointer;
    border-radius: 2px;
    box-shadow: none;
    align-self: auto;
    transition: background 0.1s, color 0.1s;
}
.add-btn:hover {
    background: var(--ink);
    color: var(--paper);
    transform: none;
    box-shadow: none;
}
.add-btn--tailor:hover { background: var(--rust); border-color: var(--rust); }
.reconstruct-btn {
    background: transparent;
    color: var(--muted);
    border: 1px dashed var(--rule);
    padding: 5px 10px;
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    cursor: pointer;
    border-radius: 2px;
    transition: background 0.1s, color 0.1s, border-color 0.1s;
    align-self: auto;
}
.reconstruct-btn:hover {
    color: var(--ink);
    border-color: var(--ink);
    border-style: solid;
    background: var(--paper);
}
.reconstruct-target-label { margin: 0 0 4px; }
.remove-pick {
    background: transparent;
    color: var(--muted);
    border: 1px solid var(--rule);
    padding: 4px 10px;
    font-size: 14px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    border-radius: 2px;
    box-shadow: none;
    align-self: auto;
}
.remove-pick:hover {
    color: var(--danger);
    border-color: var(--danger);
    background: var(--paper);
    transform: none;
    box-shadow: none;
}

.section-article-body {
    font-family: var(--serif);
    font-size: 14px;
    color: var(--ink-2);
    line-height: 1.6;
    word-wrap: break-word;
    margin: 0;
}

/* Markdown elements rendered inside section bodies, cards, and blockquotes. */
.section-article-body > *:first-child,
.card-body > *:first-child,
.mini-card-body > *:first-child,
details.source blockquote > *:first-child { margin-top: 0; }
.section-article-body > *:last-child,
.card-body > *:last-child,
.mini-card-body > *:last-child,
details.source blockquote > *:last-child { margin-bottom: 0; }

.section-article-body p,
.card-body p,
.mini-card-body p,
details.source blockquote p {
    margin: 0 0 10px;
    line-height: 1.55;
}
.section-article-body ul,
.section-article-body ol,
.card-body ul,
.card-body ol,
.mini-card-body ul,
.mini-card-body ol,
details.source blockquote ul,
details.source blockquote ol {
    margin: 0 0 10px;
    padding-left: 22px;
}
.section-article-body li,
.card-body li,
.mini-card-body li,
details.source blockquote li {
    margin: 2px 0;
    line-height: 1.5;
}
.section-article-body h1, .section-article-body h2, .section-article-body h3,
.card-body h1, .card-body h2, .card-body h3,
.mini-card-body h1, .mini-card-body h2, .mini-card-body h3,
details.source blockquote h1, details.source blockquote h2, details.source blockquote h3 {
    /* Inline section headings inside a body — used for joined cards and for
       sub-headings inside sections. Smaller and tighter than top-level h2s. */
    font-family: var(--serif);
    font-size: 14px;
    font-weight: 700;
    color: var(--ink);
    margin: 16px 0 6px;
    text-transform: none;
    letter-spacing: 0;
    background: none;
    padding: 0;
    display: block;
}
.section-article-body h2,
.card-body h2,
.mini-card-body h2,
details.source blockquote h2 {
    font-size: 15px;
    border-bottom: 1px solid var(--rule);
    padding-bottom: 2px;
}
.section-article-body strong,
.card-body strong,
.mini-card-body strong,
details.source blockquote strong { color: var(--ink); }
.section-article-body code,
.card-body code,
.mini-card-body code,
details.source blockquote code {
    font-family: var(--mono);
    background: var(--paper-3);
    padding: 1px 5px;
    border-radius: 2px;
    font-size: 0.92em;
}

details.source blockquote { overflow-x: auto; }

/* ---- Card builder side panel ---- */

.card-builder {
    position: sticky;
    top: 76px;
    max-height: calc(100vh - 100px);
    overflow-y: auto;
    background: var(--paper-2);
    border-left: 3px solid var(--ink);
    padding: 16px 18px;
    border-radius: 2px;
}
.card-builder h3 { margin: 0 0 12px; display: flex; align-items: center; gap: 8px; }
.card-count {
    background: var(--ink);
    color: var(--paper);
    font-family: var(--mono);
    font-size: 11px;
    padding: 2px 8px;
    border-radius: 10px;
    font-weight: 700;
    font-style: normal;
}

.builder-groups {
    list-style: none;
    padding: 0;
    margin: 0 0 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.builder-group {
    background: var(--paper);
    padding: 10px 12px;
    border-radius: 2px;
    border-left: 3px solid var(--rule);
    cursor: pointer;
}
.builder-group.active { box-shadow: inset 0 0 0 1px var(--ink); }
.builder-group-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
}
.builder-group-num {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 700;
    flex-shrink: 0;
}
.builder-group-label {
    flex: 1;
    font-family: var(--serif);
    font-size: 13px;
    color: var(--ink-2);
    line-height: 1.35;
    word-wrap: break-word;
    min-width: 0;
}
.remove-group {
    background: transparent;
    border: 1px solid var(--rule);
    color: var(--muted);
    padding: 2px 8px;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    border-radius: 2px;
    box-shadow: none;
    align-self: auto;
}
.remove-group:hover {
    color: var(--danger);
    border-color: var(--danger);
    background: var(--paper);
    transform: none;
    box-shadow: none;
}
.builder-group-kind {
    display: flex;
    gap: 14px;
    font-family: var(--mono);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--muted);
}
.builder-group-kind label {
    flex-direction: row;
    align-items: center;
    gap: 4px;
    text-transform: uppercase;
    cursor: pointer;
}
.builder-group-kind input[type="radio"] { margin: 0; }

/* ---- Per-section rows inside a card group ---- */

.builder-section-list {
    list-style: none;
    padding: 0;
    margin: 6px 0 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.builder-section {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 0;
    border-top: 1px dotted var(--rule);
    flex-wrap: wrap;
}
.builder-section-list li:first-child { border-top: none; }
.builder-section-name {
    flex: 1 1 60%;
    font-family: var(--serif);
    font-size: 12px;
    color: var(--ink-2);
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
.builder-section-toggle {
    display: flex;
    gap: 4px;
    align-items: center;
}
.kind-pill {
    font-family: var(--mono);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 2px 7px;
    border: 1px solid var(--rule);
    border-radius: 10px;
    cursor: pointer;
    color: var(--muted);
    flex-direction: row;
    gap: 3px;
    align-items: center;
    background: var(--paper);
    transition: background 0.1s, color 0.1s, border-color 0.1s;
}
.kind-pill:has(input:checked) {
    color: var(--paper);
    border-color: var(--ink);
    background: var(--ink);
}
.kind-pill--tailor:has(input:checked) {
    background: var(--rust);
    border-color: var(--rust);
}
.kind-pill input[type="radio"] {
    /* Hide the actual radio, the pill itself is the visual */
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    margin: 0;
}
.builder-section-remove {
    background: transparent;
    border: 1px solid var(--rule);
    color: var(--muted);
    padding: 0 6px;
    font-size: 12px;
    line-height: 1.4;
    cursor: pointer;
    border-radius: 2px;
    box-shadow: none;
    align-self: auto;
}

/* ---- Per-card tailor prompt ---- */

.builder-prompt {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dotted var(--rule);
}
.builder-prompt label {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.builder-prompt-label {
    font-family: var(--mono);
    font-size: 10px;
    color: var(--rust);
    text-transform: uppercase;
    letter-spacing: 0.14em;
    font-weight: 700;
}
.builder-prompt-input {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--rule);
    border-radius: 2px;
    background: var(--paper);
    color: var(--ink-2);
    font-family: var(--serif);
    font-size: 14px;
    line-height: 1.5;
    resize: vertical;
    min-height: 88px;
}
.builder-section-remove:hover {
    color: var(--danger);
    border-color: var(--danger);
    background: var(--paper);
    transform: none;
    box-shadow: none;
}

.builder-actions {
    display: flex;
    gap: 8px;
    margin-top: 12px;
}
.builder-actions button.primary {
    background: var(--ink);
    color: var(--paper);
    flex: 1;
    padding: 10px 16px;
    font-size: 14px;
    align-self: auto;
}
.builder-actions button.secondary {
    background: var(--paper);
    color: var(--ink);
    border: 1px solid var(--ink);
    box-shadow: none;
    padding: 10px 14px;
    font-size: 13px;
    align-self: auto;
}
.builder-actions button.secondary:hover {
    background: var(--ink);
    color: var(--paper);
    transform: none;
    box-shadow: none;
}

#submit-status {
    margin: 10px 0 0;
    font-size: 13px;
}
#submit-status.error { color: var(--danger); font-style: normal; font-family: var(--mono); font-size: 12px; }

.existing-cards { margin-top: 48px; }

.mini-card-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.mini-card {
    position: relative;
    padding: 10px 28px 10px 12px;
    background: var(--paper-2);
    border-left: 3px solid var(--ink);
    border-radius: 2px;
    font-family: var(--serif);
    font-size: 13px;
    line-height: 1.5;
    color: var(--ink-2);
}
.mini-card--summary { border-left-color: var(--rust); }
.mini-card-head {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-bottom: 4px;
    flex-wrap: wrap;
}
.mini-card-kind {
    font-family: var(--mono);
    font-size: 9px;
    color: var(--rust);
    text-transform: uppercase;
    letter-spacing: 0.16em;
    font-weight: 700;
}
.mini-card-label {
    font-style: italic;
    font-weight: 600;
    color: var(--ink);
    font-size: 12px;
}
.mini-card-body {
    margin: 0;
    white-space: pre-wrap;
    word-wrap: break-word;
}
.mini-card-del {
    position: absolute;
    top: 6px;
    right: 6px;
    margin: 0;
}
.mini-card-del button {
    box-shadow: none;
    padding: 2px 8px;
    font-size: 12px;
    line-height: 1;
}
.mini-card-list .empty {
    background: transparent;
    border: 1px dashed var(--rule);
    padding: 16px;
    text-align: center;
    color: var(--muted);
    font-style: italic;
    border-radius: 2px;
}

/* ---- Home page two-column layout ---- */

.home-layout {
    display: grid;
    /* Left column sizes to its content (the class cards), right column is
       a fixed 400. No more 1fr stretching empty space between them. */
    grid-template-columns: minmax(420px, max-content) 400px;
    gap: 20px;
    align-items: start;
    /* Sit centered in the viewport. The natural width of the layout is just
       widest-class-card + 340 + 20, so it stays compact. */
    width: fit-content;
    max-width: calc(100vw - 48px);
    margin-left: auto;
    margin-right: auto;
}
.home-main-col { min-width: 0; }
.home-todo-col {
    position: sticky;
    top: 76px;
    max-height: calc(100vh - 100px);
    overflow-y: auto;
}

/* "+ Add a syllabus" button next to the Your courses heading */
section h2 .add-syllabus-btn,
.add-syllabus-btn {
    margin-left: 10px;
    background: var(--paper-2);
    color: var(--ink);
    border: 1.5px solid var(--ink);
    padding: 0;
    width: 28px;
    height: 28px;
    font-family: var(--serif);
    font-size: 18px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    border-radius: 50%;
    box-shadow: 1px 1px 0 var(--rust);
    align-self: auto;
    text-transform: none;
    letter-spacing: 0;
    vertical-align: middle;
}
.add-syllabus-btn:hover {
    background: var(--ink);
    color: var(--paper);
    transform: translate(-1px, -1px);
    box-shadow: 2px 2px 0 var(--rust);
}
.add-syllabus-btn:active {
    transform: translate(1px, 1px);
    box-shadow: 0 0 0 var(--rust);
}

/* ---- Modal (syllabus upload) ---- */

/* `.react-modal-overlay` is the React-owned variant: same backdrop styling,
   but a distinct class so modal.js's delegated open/close/Escape handlers
   (which match the bare `.modal-overlay` token) leave it alone. React manages
   its own open/close state instead. */
.modal-overlay,
.react-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    /* flex-start so a tall modal pins to the top of the viewport instead
       of overflowing both above and below center — the X always lands on
       a reachable spot. */
    align-items: flex-start;
    justify-content: center;
    z-index: 1000;
    padding: 24px;
    overflow-y: auto;
}
.modal-overlay[hidden] { display: none; }
body.modal-open { overflow: hidden; }
.modal-dialog {
    background: var(--paper);
    color: var(--ink-2);
    max-width: 560px;
    width: 100%;
    max-height: calc(100vh - 48px);
    overflow-y: auto;
    border-radius: 4px;
    border-left: 3px solid var(--ink);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35);
    padding: 24px 28px 28px;
}
.modal-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin: -24px -28px 8px;
    padding: 18px 28px 12px;
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
}
.modal-head h2 {
    margin: 0;
    background: none;
    padding: 0;
}
.modal-close {
    background: transparent;
    color: var(--muted);
    border: 1px solid var(--rule);
    padding: 4px 12px;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    border-radius: 2px;
    box-shadow: none;
    align-self: flex-start;
    transition: color 0.1s, border-color 0.1s;
}
.modal-close:hover {
    color: var(--danger);
    border-color: var(--danger);
    transform: none;
    box-shadow: none;
}

/* ---- Today-list block (shared partial styling) ---- */

.today-list-block {
    background: var(--paper-2);
    border-left: 3px solid var(--ink);
    border-radius: 2px;
    padding: 18px 22px;
}
.today-list-head {
    margin-bottom: 14px;
}
.today-list-head h2 {
    margin: 0;
    display: inline-block;
}
.today-list-head .subtle { font-size: 13px; }

.todo-section { margin-top: 18px; }
.todo-section-head {
    margin: 14px 0 8px;
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 700;
    color: var(--rust);
    text-transform: uppercase;
    letter-spacing: 0.16em;
    font-style: normal;
}
.overdue-section .todo-section-head { color: var(--danger); }

/* Overdue rows: red title + red drawer cap. Today and overdue share one
   UL inside the class-block, so the red text is the only inline signal
   the row is past-due (no divider, no per-row "overdue" badge). The
   drawer cap names it explicitly when the user clicks in. */
.todo-row.is-overdue .todo-title { color: var(--danger); }
.todo-drawer-overdue {
    margin-bottom: 8px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--rule);
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 700;
    color: var(--danger);
    text-transform: uppercase;
    letter-spacing: 0.16em;
}

/* Add-task form with class picker (shared, both views).
   Stacked single-column layout so it fits snugly inside the ~360px sidebar
   regardless of input intrinsic widths. min-width:0 on labels prevents the
   text input's internal default size (~20em) from forcing column overflow. */
.add-task-form {
    background: var(--paper);
    padding: 12px;
    border-radius: 2px;
    border: 1px dashed var(--rule);
    margin: 0 0 14px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    box-sizing: border-box;
    max-width: 100%;
}
.add-task-form label {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    width: 100%;
}
.add-task-form label[hidden] { display: none; }
.add-task-form .add-task-range-toggle {
    align-self: flex-start;
    margin-top: -2px;
    box-shadow: none;
    padding: 0;
}
/* Form-wide button styling adds a paper-aesthetic box; opt link-btns
   (Manage tags, range toggle) back out so they read as inline links. */
.add-task-form .link-btn {
    box-shadow: none;
    padding: 0;
    background: none;
    border: 0;
    align-self: flex-start;
}
.add-task-form .add-task-label {
    font-family: var(--mono);
    font-size: 9px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.add-task-form input[type="text"],
.add-task-form input[type="date"],
.add-task-form input[type="datetime-local"],
.add-task-form select {
    padding: 7px 9px;
    font-size: 13px;
    font-family: var(--serif);
    background: var(--paper-2);
    color: var(--ink-2);
    border: 1px solid var(--rule);
    border-radius: 2px;
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
}
.add-task-form button {
    padding: 7px 14px;
    font-size: 12px;
    box-shadow: 1px 1px 0 var(--rust);
    align-self: flex-start;
}

/* "+ Add task" button that opens the modal — replaces the old inline form
   in the today-list-block to save vertical space. */
.add-task-btn {
    background: var(--paper);
    color: var(--ink);
    border: 1.5px dashed var(--rule);
    padding: 10px 16px;
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    cursor: pointer;
    border-radius: 2px;
    box-shadow: none;
    width: 100%;
    align-self: stretch;
    margin-bottom: 14px;
    transition: border-color 0.1s, color 0.1s, background 0.1s;
}
.add-task-btn:hover {
    border-color: var(--ink);
    border-style: solid;
    color: var(--rust);
    background: var(--paper-3);
    transform: none;
    box-shadow: 1px 1px 0 var(--rust);
}

/* Modal-specific tweaks for the add-task form */
.modal-dialog .add-task-form {
    background: transparent;
    border: none;
    padding: 0;
    margin-top: 12px;
}
.modal-dialog .add-task-form input[type="text"],
.modal-dialog .add-task-form input[type="date"],
.modal-dialog .add-task-form input[type="datetime-local"],
.modal-dialog .add-task-form select {
    background: var(--paper);
    border: 1px solid var(--rule);
    font-size: 14px;
    padding: 9px 11px;
}
.modal-actions {
    display: flex;
    gap: 10px;
    margin-top: 6px;
    align-items: center;
}
.modal-actions button {
    align-self: auto;
    padding: 9px 18px;
    font-size: 13px;
}
.modal-actions button.secondary {
    background: var(--paper);
    color: var(--ink);
    border: 1px solid var(--ink);
    box-shadow: none;
    font-family: var(--serif);
    font-weight: 500;
}
.modal-actions button.secondary:hover {
    background: var(--ink);
    color: var(--paper);
    transform: none;
    box-shadow: none;
}

/* Drag handle on todo rows (small burger on the left) */
.todo-drag-handle {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    cursor: grab;
    display: flex;
    align-items: center;
    justify-content: center;
    user-select: none;
    -webkit-user-select: none;
    touch-action: none;
    opacity: 0.45;
    transition: opacity 0.1s;
}
.todo-row:hover .todo-drag-handle { opacity: 0.85; }
.todo-drag-handle:active { cursor: grabbing; }
.todo-burger {
    width: 12px;
    height: 9px;
    background-image: linear-gradient(to bottom,
        var(--ink) 0, var(--ink) 1.5px,
        transparent 1.5px, transparent 4px,
        var(--ink) 4px, var(--ink) 5.5px,
        transparent 5.5px, transparent 8px,
        var(--ink) 8px, var(--ink) 9px);
}

/* Inline title edit input */
.todo-edit-wrapper { flex: 1; min-width: 0; }
.todo-title-input {
    width: 100%;
    padding: 4px 8px;
    font-size: 14px;
    font-family: var(--serif);
    background: var(--paper);
    color: var(--ink-2);
    border: 1px solid var(--ink);
    border-radius: 2px;
}
.todo-row.editing { background: var(--paper-3); }
.todo-row .todo-title[data-editable="true"] {
    border-bottom: 1px dotted transparent;
}
.todo-row:hover .todo-title[data-editable="true"] {
    border-bottom-color: var(--rule);
}

/* Dragging state for todo rows */
.todo-row.dragging {
    opacity: 0.5;
    background: var(--paper);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.18);
}

/* ---- Top nav ---- */

.top-nav {
    display: flex;
    gap: 18px;
    margin: 0 auto 0 24px;
    flex: 1;
}
.top-nav a {
    font-family: var(--mono);
    font-size: 11px;
    color: var(--ink);
    text-transform: uppercase;
    letter-spacing: 0.16em;
    text-decoration: none;
    font-weight: 600;
    padding: 4px 0;
    border-bottom: 1.5px solid transparent;
}
.top-nav a:hover {
    border-bottom-color: var(--rust);
    color: var(--rust);
}

/* ---- Class page layout ---- */

/* Class page is single-column now; the task list lives in a floating
   panel triggered by .task-fab so it doesn't take a fixed sidebar slot. */
body:has(.class-page) main {
    max-width: 900px;
}
.class-page { min-width: 0; }

/* Whole-section collapse for Cards / Events on a class page. The h2 stays
   visible when collapsed so the user can still see the heading + chevron. */
details.class-section { margin-top: 32px; }
details.class-section > summary.class-section-summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 10px;
}
details.class-section > summary.class-section-summary::-webkit-details-marker { display: none; }
details.class-section > summary.class-section-summary::marker { content: ''; }
details.class-section > summary.class-section-summary h2 { margin: 0; }
details.class-section > summary.class-section-summary .section-toggle-chevron {
    margin-top: 0;
}
.class-section-body { margin-top: 12px; }

/* ---- Floating task FAB + panel ---- */

.task-fab {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 40;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 18px;
    background: var(--paper-2);
    color: var(--ink);
    border: 1.5px solid var(--ink);
    border-radius: 999px;
    font-family: var(--serif);
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
    box-shadow: 2px 3px 0 var(--ink);
    transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
}
.task-fab:hover { background: var(--paper-3); }
.task-fab:active {
    transform: translate(2px, 3px);
    box-shadow: 0 0 0 var(--ink);
}
.task-fab-icon {
    color: var(--rust);
    font-size: 16px;
    line-height: 1;
}
.task-fab.is-open .task-fab-icon { color: var(--ink); }

.task-fab-panel {
    position: fixed;
    right: 24px;
    bottom: 80px;
    z-index: 39;
    width: min(420px, calc(100vw - 48px));
    max-height: calc(100vh - 120px);
    overflow-y: auto;
    background: var(--paper);
    border: 1.5px solid var(--ink);
    border-radius: 6px;
    box-shadow: 4px 6px 0 var(--ink);
    padding: 18px 18px 22px;
}
.task-fab-panel[hidden] { display: none; }
.task-sidebar-title {
    margin: 0 0 12px;
    font-family: var(--serif);
    font-size: 13px;
    font-weight: 700;
    color: var(--ink);
    text-transform: uppercase;
    letter-spacing: 0.16em;
    background-image: linear-gradient(transparent calc(100% - 2px),
                                       var(--rust) calc(100% - 2px));
    background-repeat: no-repeat;
    display: inline-block;
    padding-bottom: 4px;
}
.task-sidebar-subhead {
    margin: 18px 0 8px;
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 700;
    color: var(--rust);
    text-transform: uppercase;
    letter-spacing: 0.16em;
    font-style: normal;
}
.add-task-form {
    background: var(--paper);
    padding: 12px;
    border-radius: 2px;
    border: 1px dashed var(--rule);
    margin: 0 0 14px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.add-task-form label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-family: var(--mono);
    font-size: 10px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.add-task-form label[hidden] { display: none; }
.add-task-form input[type="text"],
.add-task-form input[type="date"],
.add-task-form input[type="datetime-local"] {
    padding: 7px 9px;
    font-size: 13px;
    font-family: var(--serif);
    background: var(--paper-2);
    color: var(--ink-2);
    border: 1px solid var(--rule);
    border-radius: 2px;
}
.add-task-form button {
    padding: 7px 16px;
    font-size: 12px;
    align-self: flex-start;
    box-shadow: 1px 1px 0 var(--rust);
}

/* ---- Todo rows: circular toggle + title ---- */

.todo-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.todo-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 4px 8px 8px;
    /* Always reserve the 3px slit on the left so rows line up regardless
       of whether they're tagged. .has-tag overrides the border color. */
    border-left: 3px solid transparent;
    border-bottom: 1px dotted var(--rule);
    font-family: var(--serif);
    font-size: 14px;
    color: var(--ink-2);
    line-height: 1.35;
}
.todo-row:last-child { border-bottom: none; }
.todo-toggle {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
    box-shadow: none;
    align-self: center;
    transition: none;
}
.todo-toggle:hover { transform: none; box-shadow: none; }
.todo-circle {
    display: block;
    width: 18px;
    height: 18px;
    border: 1.8px solid var(--ink);
    border-radius: 50%;
    background: transparent;
    transition: background 0.12s, border-color 0.12s;
    margin: 0 auto;
}
.todo-toggle:hover .todo-circle { border-color: var(--rust); }
.todo-row.done .todo-circle {
    background: var(--rust);
    border-color: var(--rust);
    box-shadow: inset 0 0 0 3px var(--paper-2);
}
.todo-row.done .todo-title {
    text-decoration: line-through;
    color: var(--muted);
    font-style: italic;
}
.todo-title {
    flex: 1;
    min-width: 0;
    word-wrap: break-word;
}
.todo-sub-kind {
    font-family: var(--mono);
    font-size: 10px;
    color: var(--sub-kind-color, var(--rust));
    text-transform: uppercase;
    letter-spacing: 0.12em;
    flex-shrink: 0;
}

/* Tag swatch + colored row indicator (user-defined Tag on a Task). */
.todo-row.has-tag {
    border-left-color: var(--tag-color);
}
.todo-tag {
    display: inline-block;
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    padding: 1px 6px;
    border-radius: 8px;
    background: var(--tag-color, var(--rust));
    color: var(--paper);
    flex-shrink: 0;
    line-height: 1.4;
}
.day-cell-item.has-tag { border-left-color: var(--tag-color); border-left-width: 3px; }

/* Range-day fade: a task spanning multiple days renders one row/cell per
   day. Non-deadline days get a softened look so the deadline still pops.
   Same treatment for non-actionable context items (lecture topics,
   holidays) so submission deadlines stay loud. */
.todo-row.is-range-day,
.todo-row.is-context,
.day-cell-item.is-range-day,
.day-cell-item.is-context { opacity: 0.55; }
.todo-row.is-range-day .todo-title { font-style: italic; }
.todo-range {
    font-family: var(--mono);
    font-size: 10px;
    color: var(--muted);
    flex-shrink: 0;
    white-space: nowrap;
}

.subtle-hint {
    font-size: 10px;
    color: var(--muted);
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
    margin-left: 4px;
}

/* All-day checkbox sits inline like a chip below the due field.
   Specificity matters: `.add-task-form label` (used elsewhere) sets
   display:flex; flex-direction:column, which would stretch this label
   to the full form width and turn the entire row into a click target. */
.add-task-form label.add-task-allday {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: 6px;
    align-self: flex-start;
    width: max-content;
    margin-top: -2px;
    font-size: 12px;
    color: var(--ink);
    cursor: pointer;
}
.add-task-allday input[type="checkbox"] { margin: 0; cursor: pointer; }

/* When All-day is checked, the Starts-on label is dimmed + non-interactive
   to make clear that the field can't be edited while all-day is on. */
.add-task-form label.disabled {
    opacity: 0.45;
    pointer-events: none;
}
.add-task-form label.disabled input[type="datetime-local"] {
    background: var(--paper-2);
}

/* End-date field — only shown when Repeat is set; JS toggles `hidden`. */
.add-task-rrule-until { display: flex; flex-direction: column; gap: 4px; }
.add-task-rrule-until[hidden] { display: none; }

/* Stacked modal-actions for the recurring-delete dialog: full-width
   buttons one per row read more clearly than horizontal cluster. */
.modal-actions-stack {
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: stretch;
}
.modal-actions-stack button { width: 100%; }

/* Repeat / alerts / attachments — power-user fields collapsed visually so
   they fit alongside title / due / class without overwhelming the modal. */
.add-task-rrule { display: flex; flex-direction: column; gap: 4px; }
.add-task-rrule select { width: 100%; }

.add-task-alerts {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.alerts-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    min-height: 24px;
}
.alerts-chips:empty::before {
    content: 'No reminders';
    color: var(--muted);
    font-size: 11px;
    font-style: italic;
}
.alert-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px;
    border: 1px solid var(--ink-2, var(--ink));
    border-radius: 12px;
    font-family: var(--mono);
    font-size: 11px;
    background: var(--paper);
    color: var(--ink);
}
.alert-chip-remove {
    background: none;
    border: 0;
    padding: 0 0 0 2px;
    margin: 0;
    color: var(--muted);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
}
.alert-chip-remove:hover { color: var(--rust); }
.alerts-add select {
    width: 100%;
    font-size: 11px;
}

.add-task-attachments {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.attachments-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.attachment-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 6px;
    background: var(--paper-2);
    font-size: 12px;
}
.attachment-row .attachment-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.attachment-row a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.attachment-row a:hover { color: var(--rust); }
.attachment-remove {
    background: none;
    border: 0;
    padding: 0 4px;
    color: var(--muted);
    cursor: pointer;
    font-size: 14px;
}
.attachment-remove:hover { color: var(--rust); }
.attachments-upload {
    display: inline-flex;
    align-items: center;
    cursor: pointer;
}
.attachments-upload input[type="file"] {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0,0,0,0);
    border: 0;
}

/* Drawer extras — repeat / reminders / attachment summary. Tight, monospace,
   left-aligned with the existing notes block. */
.todo-drawer-meta {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 0 0 10px;
    font-family: var(--mono);
    font-size: 11px;
    color: var(--ink-2, var(--ink));
}
.todo-drawer-meta:empty { display: none; }
.todo-drawer-meta-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}
.todo-drawer-meta-label {
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 10px;
}
.todo-drawer-meta .attachments-list {
    flex: 1;
    min-width: 200px;
}

/* Repeat / attachment indicators on the row — same muted styling as the
   existing 📝 indicator. */
.todo-row-indicator {
    font-size: 12px;
    opacity: 0.6;
    margin-left: 2px;
}

.new-tag-form {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-top: -4px;
}
.new-tag-form[hidden] { display: none; }
.new-tag-form input[type="text"] {
    flex: 1;
    min-width: 0;
}
.new-tag-form input[type="color"] {
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1.5px solid var(--ink);
    border-radius: 2px;
    background: transparent;
    cursor: pointer;
    flex-shrink: 0;
}
.secondary.small {
    font-size: 11px;
    padding: 6px 10px;
}

.link-btn {
    background: none;
    border: 0;
    padding: 0;
    margin: 0;
    color: var(--rust);
    font: inherit;
    font-size: 11px;
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
}
.link-btn:hover { color: var(--ink); }
.link-btn.danger { color: var(--rust); }
.link-btn.danger:hover { color: var(--ink); }

/* ---- Imported-calendar legend (Weekly page) ---- */
.cal-legend {
    margin: 0 0 16px;
    padding: 12px 14px;
    background: var(--paper-2);
    border: 1px solid var(--paper-3);
    border-radius: 8px;
}
.cal-legend-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
.cal-legend-title {
    margin: 0;
    font-size: 14px;
    font-weight: 700;
    color: var(--ink-2);
}
.cal-legend-empty { margin: 8px 0 0; font-size: 13px; }
.cal-legend-list {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 8px 16px;
}
.cal-legend-item {
    display: flex;
    align-items: center;
    gap: 8px;
}
.cal-legend-item.is-hidden { opacity: 0.5; }
/* The Hide/Delete actions are <form>-wrapped buttons; Edit is a bare
   button. Inline forms inherit the body's tall line-height, so their
   buttons sat lower than Edit. inline-flex + center collapses each form
   to its button's height so all three actions share one baseline. */
.cal-legend-item form.inline {
    display: inline-flex;
    align-items: center;
    margin: 0;
}
.cal-swatch {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 3px;
    background: var(--cal-color, var(--rust));
    flex: 0 0 auto;
}
.cal-name { font-size: 13px; color: var(--ink-2); }
.class-block-head-imported {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-bottom: 6px;
}
.class-block-head-imported .class-code {
    font-family: var(--serif);
    font-weight: 700;
    font-style: italic;
    color: var(--muted);
}
.import-source-toggle {
    display: flex;
    gap: 16px;
    font-size: 14px;
    margin: 4px 0;
}
.import-source-toggle label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.tag-manage-list {
    list-style: none;
    margin: 12px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.tag-manage-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px;
    border: 1px solid var(--rule);
    border-radius: 2px;
    background: var(--paper);
}
.tag-manage-row.is-system { background: var(--paper-2); }
.tag-manage-row .tag-swatch {
    display: inline-block;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 1px solid var(--ink);
    flex-shrink: 0;
}
.tag-manage-name {
    flex: 1;
    font-family: var(--serif);
    font-size: 14px;
    color: var(--ink);
}
.tag-system-badge {
    font-family: var(--mono);
    font-size: 9px;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--muted);
    border: 1px solid var(--rule);
    padding: 1px 6px;
    border-radius: 8px;
}
.tag-manage-row input[type="text"] {
    flex: 1;
    min-width: 0;
}
.tag-manage-row input[type="color"] {
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--ink);
    border-radius: 2px;
    background: transparent;
    cursor: pointer;
    flex-shrink: 0;
}
.tag-manage-actions {
    display: flex;
    gap: 6px;
    align-items: center;
    flex-shrink: 0;
}
.todo-when {
    font-family: var(--mono);
    font-size: 11px;
    color: var(--muted);
    flex-shrink: 0;
    white-space: nowrap;
}
.todo-del,
.todo-edit {
    background: transparent;
    border: 1px solid transparent;
    color: var(--muted);
    padding: 0 6px;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    border-radius: 2px;
    box-shadow: none;
    align-self: center;
    flex-shrink: 0;
}
.todo-del:hover {
    color: var(--danger);
    border-color: var(--danger);
    transform: none;
    box-shadow: none;
}
.todo-edit:hover {
    color: var(--ink);
    border-color: var(--ink);
    transform: none;
    box-shadow: none;
}
.todo-edit-icon {
    display: inline-block;
    line-height: 1;
    font-size: 13px;
}

/* Row layout: main row is the always-visible click target; the drawer sits
   below it and shows on expand. The original .todo-row's flex behavior
   moves into .todo-row-main so the drawer can stack as a block. */
.todo-row {
    flex-direction: column;
    align-items: stretch;
}
.todo-row-main {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    width: 100%;
    /* No padding here — keep existing .todo-row padding doing its job. */
}
.todo-row-main:focus-visible {
    outline: 2px solid var(--rust);
    outline-offset: 2px;
}
.todo-row-main .todo-title { flex: 1; min-width: 0; }

/* Tiny memo glyph in the row that hints "this task has notes" without
   being a button. The full notes show in the drawer when expanded. */
.todo-notes-indicator {
    font-size: 12px;
    opacity: 0.6;
    margin-left: 2px;
}

/* Drawer that opens below the row when clicked. Holds the full notes
   text and the action buttons. */
.todo-drawer {
    margin: 6px 0 4px 28px;  /* indent past drag handle + circle */
    padding: 10px 12px;
    background: var(--paper-2);
    border-left: 2px solid var(--rule);
}
.todo-row.expanded .todo-drawer { display: block; }

/* Notes content inside the drawer. Pre-wrap preserves user line breaks. */
.todo-drawer .todo-notes {
    margin: 0 0 10px;
    color: var(--ink-2);
    font-size: 13px;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
}
.todo-drawer-actions {
    display: flex;
    gap: 8px;
    align-items: center;
}
/* Override .todo-edit/.todo-del compact styles when they live in the
   drawer — we want labeled, room-to-tap buttons, not inline icons. */
.todo-drawer .todo-edit,
.todo-drawer .todo-del {
    background: transparent;
    border: 1px solid var(--ink);
    color: var(--ink);
    padding: 4px 10px;
    font-family: var(--mono);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    cursor: pointer;
    border-radius: 2px;
}
.todo-drawer .todo-del:hover {
    background: var(--danger, #b94747);
    border-color: var(--danger, #b94747);
    color: var(--paper);
}
.todo-drawer .todo-edit:hover {
    background: var(--ink);
    color: var(--paper);
}

/* Class-block drag handle — sits to the left of the class header.
   Grabbable when reordering the class blocks. */
.class-block-head-row {
    display: flex;
    align-items: baseline;
    gap: 6px;
}
.class-block-head-row .class-block-head { flex: 1; min-width: 0; }
.class-block-drag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    cursor: grab;
    opacity: 0;
    transition: opacity 120ms ease;
    flex-shrink: 0;
    align-self: center;
}
.class-block:hover .class-block-drag,
.class-block-drag:focus-visible { opacity: 0.6; }
.class-block-drag:hover { opacity: 1; }
.class-block-drag:active { cursor: grabbing; }
.class-block-drag-grip {
    width: 10px;
    height: 12px;
    background-image: linear-gradient(to bottom,
        var(--ink) 0, var(--ink) 1.5px,
        transparent 1.5px, transparent 4px,
        var(--ink) 4px, var(--ink) 5.5px,
        transparent 5.5px, transparent 8px,
        var(--ink) 8px, var(--ink) 9.5px,
        transparent 9.5px, transparent 12px);
}
.class-block.dragging {
    opacity: 0.5;
    background: var(--paper);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.18);
}

/* Personal bucket header — looks like a class header but isn't a link.
   Italic + slightly muted to differentiate from real classes. */
.class-block-head-personal {
    display: flex;
    gap: 12px;
    align-items: baseline;
    margin-bottom: 6px;
    padding: 6px 0;
    border-bottom: 1.5px solid var(--ink);
}
.class-block-head-personal .class-code {
    font-family: var(--serif);
    font-weight: 700;
    font-style: italic;
    color: var(--muted);
}

/* Notes textarea in add/edit task modals. Matches the existing input style. */
.add-task-notes textarea {
    width: 100%;
    padding: 8px 10px;
    font-family: var(--serif);
    font-size: 14px;
    color: var(--ink-2);
    background: var(--paper);
    border: 1px solid var(--ink);
    border-radius: 2px;
    resize: vertical;
    min-height: 70px;
}

/* ---- Today view ---- */

.todo-section { margin-top: 24px; }
.todo-section h2 {
    margin-bottom: 12px;
}
.overdue-section h2 {
    color: var(--danger);
    background-image: linear-gradient(transparent calc(100% - 2px),
                                       var(--danger) calc(100% - 2px));
}
.class-block {
    margin-bottom: 18px;
}
.class-block-head {
    display: flex;
    gap: 12px;
    align-items: baseline;
    text-decoration: none;
    color: inherit;
    margin-bottom: 6px;
    padding: 6px 0;
    border-bottom: 1.5px solid var(--ink);
}
.class-block-head:hover .class-code,
.class-block-head:hover .class-name {
    color: var(--rust);
}
.class-block-head .class-code {
    font-family: var(--serif);
    font-weight: 700;
    color: var(--ink);
    font-size: 14px;
    letter-spacing: -0.01em;
}
.class-block-head .class-name {
    font-family: var(--serif);
    font-style: italic;
    font-size: 13px;
    color: var(--muted);
}

/* ---- Month view (Mon-Sun, 6 weeks) ---- */

.month-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    /* Break out of <main>'s 24px horizontal padding so the sticky bar's
       background spans edge-to-edge of the viewport while content stays
       inset. Padding compensates for the negative margin. */
    margin: 0 -24px;
    padding: 16px 24px 12px;
    /* Stick below the masthead (which is ~64px tall) so this row stays
       visible as you scroll. Day-cell-heads no longer inherit sticky. */
    position: sticky;
    top: 64px;
    background: var(--paper);
    z-index: 5;
}
@media (max-width: 480px) {
    .month-header { margin: 0 -18px; padding: 16px 18px 12px; }
}
.month-header h1 { margin: 0; }
.month-nav { display: flex; gap: 8px; }
.month-nav-btn {
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    padding: 6px 12px;
    border: 1.5px solid var(--ink);
    border-radius: 2px;
    background: var(--paper);
    color: var(--ink);
    text-decoration: none;
    cursor: pointer;
}
.month-nav-btn:hover { background: var(--ink); color: var(--paper); }

.month-weekdays {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 4px;
    margin-top: 16px;
    margin-bottom: 6px;
}
.month-weekdays > div {
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 700;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    padding: 0 4px;
}

.month-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    grid-auto-rows: minmax(120px, 1fr);
    gap: 4px;
}

/* On the week page, stretch the calendar to fill the viewport so we don't
   have a big empty band below the grid on tall monitors. The :has()
   selector scopes this to pages that render the grid, leaving home/class
   layout untouched. */
body:has(.month-grid) { min-height: 100vh; display: flex; flex-direction: column; }
/* margin-inline: 0 cancels the base `main { margin: 0 auto }`. Auto side
   margins in a flex column make the item shrink-to-fit its content and
   center — so an empty grid rendered narrow and only "widened" once an
   event gave a cell more content. Zeroing them lets main stretch to the
   full body width, so the calendar always fills the screen. */
body:has(.month-grid) main { flex: 1; display: flex; flex-direction: column; margin-inline: 0; }
body:has(.month-grid) .month-grid { flex: 1; }

.day-cell {
    background: var(--paper-2);
    border: 1px solid var(--rule);
    border-radius: 2px;
    padding: 6px 8px;
    min-height: 120px;
    min-width: 0;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 6px;
    transition: background 0.15s ease, border-color 0.15s ease;
}
.day-cell:hover,
.day-cell:focus-visible {
    background: var(--paper-3);
    border-color: var(--ink);
    outline: none;
}
.day-cell.is-today {
    border-color: var(--rust);
    border-width: 2px;
    padding: 5px 7px;
}
.day-cell.is-out-of-month {
    background: var(--paper);
    opacity: 0.5;
}
.day-cell template { display: none; }

.day-cell-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 4px;
}
.day-cell-date {
    font-family: var(--serif);
    font-size: 13px;
    font-weight: 700;
    color: var(--ink);
}
.day-cell-head .day-today-tag {
    background: var(--rust);
    color: var(--paper);
    font-family: var(--mono);
    font-size: 8px;
    padding: 1px 5px;
    border-radius: 6px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.day-cell-items {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    overflow: hidden;
}
.day-cell-item {
    font-size: 12px;
    line-height: 1.5;
    color: var(--ink-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 4px 6px;
    background: var(--paper);
    border-left: 2px solid var(--rule);
    border-radius: 2px;
}
.day-cell-item.done { text-decoration: line-through; color: var(--muted); }
.day-cell-code {
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 700;
    color: var(--rust);
    margin-right: 4px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

/* ---- Responsive: stack class layout + collapse week grid on small screens ---- */

@media (max-width: 900px) {
    .home-layout { grid-template-columns: 1fr; }
    .home-todo-col { position: static; max-height: none; margin-top: 24px; }
    .task-fab { right: 16px; bottom: 16px; padding: 9px 14px; font-size: 13px; }
    .task-fab-panel { right: 16px; bottom: 70px; }
    .day-cell { min-height: 80px; padding: 4px 6px; }
    .day-cell-item { font-size: 10px; }
    .day-cell-code { display: none; }
}

/* ---- Mobile fine-tuning ---- */

@media (max-width: 900px) {
    .sections-page { grid-template-columns: 1fr; }
    .card-builder {
        position: static;
        max-height: none;
        margin-top: 24px;
    }
}

@media (max-width: 480px) {
    main { padding: 28px 18px 80px; }
    h1 { font-size: 24px; }
    h1 .subtle { display: block; font-size: 16px; margin: 4px 0 0; }
    .class-card { grid-template-columns: 1fr; gap: 4px; }
    .event-list li { grid-template-columns: 80px 1fr; gap: 10px; }
    .event-list .when { grid-column: 1 / -1; }
    .event-list .event-add-cal { grid-column: 1 / -1; justify-self: start; }
    .section-article--lvl2 { margin-left: 8px; }
    .section-article--lvl3 { margin-left: 16px; }
    .section-article-heading { font-size: 16px !important; }
    .section-article-actions { width: 100%; margin-top: 6px; }
}

/* ============================================================
   Mobile responsive pass — hamburger nav, stacked month grid,
   touch-sized controls. 640px = phone / small tablet.
   ============================================================ */

/* Hamburger control. The checkbox is never visible (the label drives
   it); CSS-only so the menu works before todo.js loads. Hidden on
   desktop where the inline nav row is fine. */
.nav-toggle-cb {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}
.nav-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-left: auto;
    border: 1px solid var(--ink);
    border-radius: 2px;
    background: transparent;
    cursor: pointer;
    box-shadow: none;
}
.nav-toggle-bars {
    position: relative;
    width: 20px;
    height: 2px;
    background: var(--ink);
}
.nav-toggle-bars::before,
.nav-toggle-bars::after {
    content: "";
    position: absolute;
    left: 0;
    width: 20px;
    height: 2px;
    background: var(--ink);
    transition: transform 0.15s ease, top 0.15s ease;
}
.nav-toggle-bars::before { top: -6px; }
.nav-toggle-bars::after  { top: 6px; }
/* Morph to an X while the menu is open. */
.nav-toggle-cb:checked ~ .nav-toggle .nav-toggle-bars { background: transparent; }
.nav-toggle-cb:checked ~ .nav-toggle .nav-toggle-bars::before { top: 0; transform: rotate(45deg); }
.nav-toggle-cb:checked ~ .nav-toggle .nav-toggle-bars::after  { top: 0; transform: rotate(-45deg); }

/* Weekday label inside a day cell — only shown in the stacked
   single-column mobile calendar, hidden in the desktop grid. */
.day-cell-weekday { display: none; }

@media (max-width: 640px) {
    /* --- Header → hamburger dropdown --- */
    .nav-toggle { display: inline-flex; }
    .top-nav {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        gap: 0;
        margin: 0;
        background: var(--paper);
        border-bottom: 1.5px solid var(--ink);
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
        z-index: 20;
    }
    .nav-toggle-cb:checked ~ .top-nav { display: flex; }
    .top-nav a {
        padding: 16px 24px;
        border-bottom: 1px solid var(--rule);
        font-size: 13px;
    }
    .top-nav a:last-child { border-bottom: none; }
    .header-actions { margin-left: 0; }

    /* --- Month calendar → single-column agenda --- */
    .month-weekdays { display: none; }
    .month-grid {
        grid-template-columns: 1fr;
        grid-auto-rows: auto;
        gap: 8px;
    }
    .day-cell {
        min-height: 0;
        padding: 12px 14px;
    }
    .day-cell.is-today { padding: 11px 13px; }
    /* A long faded list of other-month padding days is just noise in
       a vertical scroll — drop them on mobile. */
    .day-cell.is-out-of-month { display: none; }
    .day-cell-weekday {
        display: inline;
        font-family: var(--mono);
        font-size: 11px;
        font-weight: 700;
        color: var(--rust);
        text-transform: uppercase;
        letter-spacing: 0.1em;
        margin-right: 8px;
    }
    .day-cell-date { font-size: 15px; }
    .day-cell-item { font-size: 13px; }

    /* Task rows: the time + tag chips are flex-shrink:0, so in a narrow
       container (320px home column, the day modal) they reserved space on
       the title's row and squeezed it into a one-word-per-line column.
       flex-wrap lets the meta drop to its own line ONLY when the title is
       long enough to need the room — short titles keep the single row.
       margin-left:auto on the first meta element (whatever immediately
       follows the title: .todo-when / .todo-range / .todo-tag) tucks the
       wrapped meta into the bottom-right instead of under the drag handle. */
    .todo-row-main { flex-wrap: wrap; row-gap: 2px; }
    /* flex-basis:auto (not the default `flex:1` → basis 0%) so a long title
       contributes its content width to line-breaking and bumps the meta to
       the next line; a short title still fits beside the meta on one row. */
    .todo-row-main .todo-title { flex: 1 1 auto; min-width: 0; }
    .todo-row-main .todo-title + * { margin-left: auto; }
}

/* Touch devices: grow tap targets to ~44px without touching the
   desktop look. Scoped to coarse pointers so mouse users keep the
   tight layout. */
@media (pointer: coarse) {
    .todo-toggle {
        width: 40px;
        height: 40px;
        margin: -9px 0;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .todo-del,
    .todo-edit { padding: 10px 12px; }
    .modal-close { padding: 10px 16px; min-height: 40px; }
    .month-nav-btn { padding: 11px 16px; }
    .modal-actions button { min-height: 44px; }
}

/* ---- Admin dashboard table (desktop) ---- */
.admin-table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 20px;
    font-size: 14px;
}
.admin-table th,
.admin-table td { padding: 8px 10px; text-align: left; }
.admin-table thead tr { border-bottom: 1px solid var(--ink); }
.admin-table tbody tr { border-bottom: 1px solid var(--rule); }
.admin-table .admin-status-on { color: var(--accent, #5b9d5b); }
.admin-table .admin-action-form { margin: 0; }
.admin-status-on { color: var(--accent, #5b9d5b); }

/* Per-row action buttons sit side by side (Grant/Revoke + Block/Unblock). */
.admin-action-group {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* Global shared-key kill-switch banner above the user table. */
.admin-global-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 20px;
    padding: 14px 16px;
    border: 1px solid var(--rule);
    border-radius: 8px;
}
.admin-global-toggle-text { display: flex; flex-direction: column; gap: 4px; }
.admin-global-toggle .admin-action-form { margin: 0; }

@media (max-width: 640px) {
    /* The masthead was 7px too wide at 320px (logo + hamburger +
       Dark + Logout). Tighten padding + gap so it fits the smallest
       phones without a horizontal scrollbar. */
    body > header { padding: 14px 16px; gap: 10px; }
    .theme-toggle { padding: 5px 9px; letter-spacing: 0.08em; }

    /* Admin user table → one card per user. A 5-column table can't
       fit a phone; stacking each cell with its label keeps every
       value readable and the page inside the viewport. */
    .admin-table thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
    }
    .admin-table,
    .admin-table tbody,
    .admin-table tr,
    .admin-table td { display: block; width: 100%; }
    .admin-table tr {
        border: 1px solid var(--rule);
        border-radius: 3px;
        margin-bottom: 12px;
        padding: 6px 12px;
        background: var(--paper-2);
    }
    .admin-table td {
        display: flex;
        justify-content: space-between;
        gap: 12px;
        padding: 7px 0;
        border: none;
        overflow-wrap: anywhere;
    }
    .admin-table td::before {
        content: attr(data-label);
        flex-shrink: 0;
        font-family: var(--mono);
        font-size: 11px;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.08em;
        color: var(--muted);
    }
    .admin-table td:last-child { padding-top: 10px; }
    .admin-table .admin-action-form { width: 100%; }
    .admin-table .admin-action-form button { width: 100%; }
}

.test-link {
    display: inline-block;
    font-family: var(--mono);
    font-size: 12px;
    color: var(--ink);
    border: 1px dashed var(--rule);
    padding: 4px 10px;
    border-radius: 2px;
    text-decoration: none;
    transition: background 0.1s, border-color 0.1s;
}
.test-link:hover {
    background: var(--paper-2);
    border-color: var(--ink);
    border-style: solid;
}

.test-index-list {
    list-style: none;
    padding: 0;
    margin: 16px 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.test-index-link {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 14px;
    align-items: baseline;
    padding: 12px 16px;
    background: var(--paper-2);
    border: 1.5px solid var(--ink);
    border-radius: 3px;
    text-decoration: none;
    color: var(--ink);
    transition: background 0.12s, transform 0.12s;
}
.test-index-link:hover {
    background: var(--paper-3);
    transform: translateX(3px);
}
.test-index-cls {
    font-family: var(--serif);
    font-weight: 700;
    font-size: 16px;
    color: var(--rust);
}
.test-index-name {
    font-family: var(--serif);
    font-size: 14px;
    color: var(--ink);
}
.test-index-meta {
    font-family: var(--mono);
    font-size: 11px;
    color: var(--muted);
}

/* ---- Test PDF view (sandbox) ---- */

body:has(.test-layout) main {
    max-width: 1400px;
}
.test-layout {
    height: calc(100vh - 220px);
    min-height: 500px;
}
.test-pdf-pane {
    background: var(--paper-2);
    border: 1.5px solid var(--ink);
    border-radius: 4px;
    overflow: hidden;
    min-width: 0;
    height: 100%;
}
.test-pdf-iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

@media (max-width: 900px) {
    .test-layout { height: auto; }
    .test-pdf-pane { height: 60vh; }
}
