/* Real EAWR Oilers school colors (maroon/gold) site-wide -- every page
   (home, RSVP, helper dashboard, owner settings, memories gallery) shares
   the same --accent/--accent-2, an explicit choice to unify the whole site
   under one brand rather than keep internal pages on a separate neutral
   palette. Dark mode lightens both a step for legibility as plain text/
   borders against a dark background; filled buttons ignore this shift and
   stay the true maroon (see .btn below) since a filled background carries
   its own contrast. */
:root {
  --bg: #f7f5f0;
  --panel: #ffffff;
  --text: #1f2430;
  --muted: #6b7280;
  --accent: #6b0f1a;
  --accent-2: #d4af37;
  --border: #e3ddd0;
  --ok: #1a7a44;
  --warn: #b8860b;
  --danger: #b91c1c;
  --radius: 12px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #15161c;
    --panel: #1f212b;
    --text: #eceaf0;
    --muted: #9aa0ac;
    --accent: #d97b8a;
    --accent-2: #e6c65c;
    --border: #313342;
  }
}

/* The crest SVG itself uses hardcoded hex (not var()) since SVG
   presentation attributes don't reliably resolve custom properties across
   browsers, and these are fixed brand colors that never need to respond to
   theme changes anyway -- see templates/_crest.html. */

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  line-height: 1.5;
}

.wrap {
  max-width: 720px;
  margin: 0 auto;
  padding: 2rem 1.25rem 4rem;
}

.wrap.wide {
  max-width: 1900px;
}

header.hero {
  text-align: center;
  padding: 2rem 1rem 1.5rem;
  border-bottom: 3px solid var(--accent-2);
  margin-bottom: 1.5rem;
}

header.hero .crest {
  display: block;
  margin: 0 auto 0.75rem;
}

header.hero .eyebrow {
  color: var(--accent);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-size: 0.8rem;
  font-weight: 700;
}

header.hero h1 {
  margin: 0.4rem 0 0;
  font-size: 1.9rem;
}

header.hero .dashboard-nav {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin-top: 0.75rem;
  font-size: 0.9rem;
}

header.hero .dashboard-nav a {
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

header.hero .dashboard-nav a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

header.hero .hero-sub {
  margin: 0.6rem auto 0;
  max-width: 46rem;
  color: var(--muted);
  font-size: 1rem;
  line-height: 1.55;
}

.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem 1.5rem;
  margin-bottom: 1.25rem;
}

/* Collapsible dashboard sections -- clicking a card's heading hides
   everything else in that card. Targets any direct child that isn't the
   h3, so it works uniformly regardless of how many toolbar/list/textarea
   siblings a given card happens to have. Scoped to .dashboard-page (only
   dashboard.html's <body> carries that class) since style.css is shared
   site-wide -- a bare ".card > h3" rule leaked the pointer cursor and arrow
   onto the public landing page's and /owner's card headings too, which have
   no actual collapse behavior wired up (dashboard.js isn't loaded there). */
.dashboard-page .card > h3 {
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.dashboard-page .card > h3::before {
  content: "\25be";
  font-size: 0.7em;
  color: var(--muted);
  transition: transform 0.15s ease;
  display: inline-block;
}

.dashboard-page .card.collapsed > h3::before {
  transform: rotate(-90deg);
}

.dashboard-page .card.collapsed > *:not(h3) {
  display: none;
}

/* Unread/new-activity badge on a section heading -- visible whether the
   card is collapsed or not, so something new doesn't go unnoticed just
   because every section starts minimized. Empty (no count) means nothing
   new, so dashboard.js only fills in text when there's a nonzero count. */
.new-badge:empty {
  display: none;
}

.new-badge {
  background: var(--accent);
  color: #fff;
  border-radius: 999px;
  padding: 0.05rem 0.55rem;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1.5;
}

.details-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
}

.detail dt {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 0.2rem;
}

.detail dd {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
}

.tbd {
  color: var(--warn);
  font-style: italic;
  font-weight: 500;
}

/* Every button site-wide renders as a solid maroon fill -- including what
   used to be the outlined ".secondary" style -- and stays the true maroon
   in dark mode too rather than following --accent's lighter dark-mode
   shift. A filled button carries its own contrast against any background,
   so there's no legibility reason to lighten it for dark mode. */
.btn,
.btn.secondary {
  display: inline-block;
  background: #6b0f1a;
  color: #fff;
  border: none;
  border-radius: 999px;
  padding: 0.85rem 1.75rem;
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

.btn:hover,
.btn.secondary:hover {
  opacity: 0.92;
}

.btn.small {
  padding: 0.4rem 0.9rem;
  font-size: 0.85rem;
  border-radius: 8px;
}

.center { text-align: center; }

/* Honeypot spam-trap field: invisible to sighted users and skipped in tab
   order, but present in the DOM and not display:none, since some bots
   specifically skip display:none/visibility:hidden fields when
   auto-filling. Real visitors never see or fill it; anything that does is
   almost certainly a bot. */
.hp-field {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.field {
  margin-bottom: 1.1rem;
}

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

.field .hint {
  font-size: 0.8rem;
  color: var(--muted);
  font-weight: 400;
  margin-top: 0.25rem;
}

input[type=text], input[type=email], input[type=tel], input[type=number], input[type=date], textarea, select {
  width: 100%;
  padding: 0.7rem 0.8rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  font-size: 1rem;
  font-family: inherit;
}

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

.radio-row {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.radio-row label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.5rem 1rem;
  font-weight: 500;
  cursor: pointer;
}

.radio-row input { width: auto; }

.suggestions {
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-top: 0.4rem;
  overflow: hidden;
  display: none;
}

.suggestions.show { display: block; }

.suggestions button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.6rem 0.8rem;
  background: var(--panel);
  border: none;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  cursor: pointer;
  font-size: 0.95rem;
}

.suggestions button:last-child { border-bottom: none; }
.suggestions button:hover { background: var(--bg); }

.pill-link {
  background: none;
  border: none;
  color: var(--accent);
  text-decoration: underline;
  font-size: 0.85rem;
  cursor: pointer;
  padding: 0;
}

.notice {
  border-radius: 8px;
  padding: 0.85rem 1rem;
  font-size: 0.95rem;
  margin-top: 1rem;
}

.notice.ok { background: rgba(26,122,68,0.12); color: var(--ok); }
.notice.err { background: rgba(185,28,28,0.12); color: var(--danger); }

/* Submit-time "is this you?" prompt -- shown when someone typed a name that
   strongly matches an existing roster entry but never clicked the
   autocomplete suggestion, so their RSVP wouldn't otherwise get linked to
   their real record and would create a duplicate. */
.match-confirm {
  background: rgba(212,175,55,0.14);
  border: 1px solid var(--accent-2);
  border-radius: 8px;
  padding: 0.9rem 1rem;
  margin-bottom: 1rem;
}

.match-confirm p { margin: 0 0 0.7rem; }

.match-confirm-actions {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.share-fallback {
  margin-top: 0.9rem;
}

.share-row {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  justify-content: center;
}

footer.foot {
  text-align: center;
  color: var(--muted);
  font-size: 0.85rem;
  margin-top: 2rem;
}

.disclaimer {
  font-size: 0.75rem;
  color: var(--muted);
  max-width: 480px;
  margin: 0.75rem auto 0;
  line-height: 1.4;
}

.dropzone {
  border: 2px dashed var(--border);
  border-radius: var(--radius);
  padding: 2rem 1rem;
  text-align: center;
  cursor: pointer;
  color: var(--muted);
  margin-bottom: 1rem;
  transition: border-color 0.15s, background 0.15s;
}

.dropzone:hover,
.dropzone.drag-over {
  border-color: var(--accent);
  background: rgba(107, 15, 26, 0.05);
}

.dropzone p {
  margin: 0.25rem 0;
}

.memory-file-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.4rem 0.75rem;
  margin-bottom: 0.4rem;
  font-size: 0.85rem;
}

.memory-file-item button {
  background: none;
  border: none;
  color: var(--danger);
  cursor: pointer;
  font-size: 0.85rem;
  padding: 0;
}

/* Dashboard */
.stats-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 0.9rem;
  margin-bottom: 1.5rem;
}

.stat {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s ease, transform 0.1s ease;
}

.stat:hover {
  border-color: var(--accent);
}

.stat:active {
  transform: scale(0.97);
}

.stat .num { font-size: 1.7rem; font-weight: 700; color: var(--accent); }
.stat .label { font-size: 0.78rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }

.toolbar {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: 1rem;
}

.toolbar input, .toolbar select {
  width: auto;
  min-width: 180px;
}

table.roster {
  width: 100%;
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--panel);
  font-size: 0.88rem;
}

table.roster th {
  text-align: left;
  padding: 0.6rem 0.5rem;
  background: var(--bg);
  border-bottom: 2px solid var(--border);
  white-space: nowrap;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  position: sticky;
  top: 0;
  z-index: 2;
}

table.roster td {
  padding: 0.35rem;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

table.roster input, table.roster select, table.roster textarea {
  padding: 0.4rem 0.5rem;
  font-size: 0.85rem;
  min-width: 0;
  width: 100%;
}

table.roster textarea { min-height: 34px; }

/* First column (yearbook name) stays visible while scrolling horizontally
   (mobile only, see below); header's first cell needs the higher z-index
   since it's sticky on both axes at once. */
table.roster th:first-child,
table.roster td:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--panel);
  box-shadow: 2px 0 4px rgba(0, 0, 0, 0.08);
}

/* First cell can carry 0-3 marker dots/checks (deceased, contacted-no-RSVP,
   responded) before the name input -- unconditional so any combination
   lines up correctly regardless of which row classes are present. */
table.roster td:first-child {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

table.roster td:first-child input {
  flex: 1;
  min-width: 0;
}

table.roster th:first-child {
  z-index: 3;
  background: var(--bg);
}

/* Deceased classmates: minimized and muted rather than styled like an
   ordinary status. The marker is a plain neutral dot (not any symbol tied
   to a specific religious tradition, since we don't know each person's
   background) with a "Deceased" tooltip for clarity, rendered as a real
   element in dashboard.js rather than injected via CSS content. */
tr.deceased-row {
  opacity: 0.6;
}

tr.deceased-row td {
  padding-top: 0.15rem;
  padding-bottom: 0.15rem;
}

.deceased-mark {
  font-size: 0.6rem;
  color: var(--muted);
  flex-shrink: 0;
}

/* Anyone who's RSVP'd or signed up (Get Updates/Volunteer) on the site --
   a light success tint on the whole row, plus a checkmark, makes it obvious
   at a glance that this person doesn't need to keep being chased. Excludes
   deceased rows (already muted/handled separately above). */
tr.responded-row {
  background: rgba(26, 122, 68, 0.08);
}

.responded-mark {
  font-size: 0.75rem;
  color: var(--ok);
  flex-shrink: 0;
}

/* We know how to reach this person (status = Contacted) but they haven't
   actually RSVP'd yet -- a plain green dot, distinct from the checkmark
   above, flags "still needs a nudge for an actual RSVP" even though
   they're not unreachable. Can appear alongside the checkmark (e.g.
   someone who signed up on the site but hasn't RSVP'd) since the two
   questions -- "have we made contact" and "have they RSVP'd" -- are
   independent of each other. */
.contacted-mark {
  font-size: 0.6rem;
  color: var(--ok);
  flex-shrink: 0;
}

.col-resize-handle {
  position: absolute;
  right: -3px;
  top: 0;
  bottom: 0;
  width: 6px;
  cursor: col-resize;
  z-index: 4;
}

.col-resize-handle:hover,
.col-resize-handle:active {
  background: var(--accent-2);
  opacity: 0.6;
}

/* Desktop: table renders at its natural width (wide container + sticky
   header scrolls with the page) so every column is visible without an
   inner scrollbar. Mobile: fall back to a horizontal scrollbox, since 12
   columns can't realistically fit a phone screen -- the sticky first
   column keeps the name in view while scrolling sideways there. */
@media (max-width: 860px) {
  .table-scroll {
    overflow-x: auto;
  }
}

.cell-with-link {
  display: flex;
  align-items: flex-start;
  gap: 0.3rem;
}

/* Social column: platform icons are the primary thing to see, not the raw
   pasted URLs -- once a value resolves to a recognizable link, dashboard.js
   skips rendering the text box entirely and shows just the button(s) (see
   linkableCell). The box only ever appears here for entering a value in the
   first place, so it doesn't need any special collapsed/grow treatment --
   just a normal compact box, stacked above the (horizontal, not stacked)
   icon row so a classmate with several social links doesn't make their row
   taller than everyone else's. */
.cell-with-link-compact {
  flex-direction: column;
  align-items: stretch;
}

.cell-with-link-compact textarea {
  min-height: 2rem;
  font-size: 0.8rem;
}

.cell-with-link-compact .link-icons {
  flex-direction: row;
  flex-wrap: wrap;
  padding-top: 0.2rem;
}

.cell-with-link input,
.cell-with-link textarea {
  flex: 1;
  min-width: 80px;
}

.signups-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.5rem;
}

.signups-columns h4 {
  margin: 0 0 0.5rem;
  font-size: 0.9rem;
}

.signup-row {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.5rem;
  font-size: 0.9rem;
}

.signup-row.resolved {
  opacity: 0.55;
}

.board-thread {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.75rem;
  font-size: 0.9rem;
}

.board-reply {
  border-left: 2px solid var(--border);
  padding: 0.4rem 0 0.4rem 0.75rem;
  margin-top: 0.5rem;
  font-size: 0.9rem;
}

.board-post-head {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.board-post-body {
  white-space: pre-wrap;
  margin: 0.3rem 0;
}

.board-reply-form {
  margin-top: 0.4rem;
}

.board-reply-form textarea {
  min-height: 2.2rem;
}

#board-poll-options-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}

#board-poll-options-list input {
  width: auto;
}

.poll-results {
  margin: 0.5rem 0;
}

.poll-option-row {
  margin-bottom: 0.4rem;
  font-size: 0.85rem;
}

.poll-option-label {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  cursor: pointer;
}

.poll-option-bar-track {
  margin-top: 2px;
  background: var(--panel-2, rgba(127, 127, 127, 0.15));
  border-radius: 4px;
  height: 8px;
  overflow: hidden;
}

.poll-option-bar-fill {
  background: var(--accent);
  height: 100%;
}

.poll-voters {
  color: var(--muted);
  font-size: 0.8rem;
}

/* Caps the Inbox/Subscribers/Volunteers lists to roughly their 3 most recent
   entries before an inner scrollbar kicks in, so a busy list doesn't push
   the rest of the dashboard down further and further as signups pile up --
   older entries are still there, just a scroll away instead of always
   visible. */
.recent-scroll {
  max-height: 260px;
  overflow-y: auto;
  padding-right: 4px;
}

.signup-row.chosen {
  border-color: var(--ok);
  border-width: 2px;
}

.venue-fields {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
}

.venue-fields input {
  width: auto;
  flex: 1 1 160px;
}

.signup-row button {
  margin-top: 0.4rem;
}

.checklist-item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.5rem 0.25rem;
  border-bottom: 1px solid var(--border);
}

.checklist-title {
  font-weight: 500;
  flex: 1 1 200px;
}

/* Compact by default (about one line); hovering or clicking in to type only
   visibly grows it if the note actually has more content than that -- a
   short note already fits, so nothing changes to look at. Grows in normal
   document flow (the whole checklist-item row gets taller, pushing rows
   below it down) rather than floating an overlay on top of everything --
   explicit choice, not a popover. min-height has to be pinned here too,
   since the generic `textarea { min-height: 80px }` rule further down this
   file would otherwise win the height fight against max-height (min-height
   always wins that conflict regardless of selector specificity). */
.checklist-notes {
  flex: 1 1 180px;
  min-width: 140px;
}

.checklist-notes textarea {
  display: block;
  width: 100%;
  min-height: 1.9rem;
  max-height: 1.9rem;
  padding: 0.3rem 0.55rem;
  font-size: 0.82rem;
  font-family: inherit;
  color: var(--muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  resize: none;
  overflow: hidden;
  transition: max-height 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

.checklist-notes textarea:hover,
.checklist-notes textarea:focus {
  max-height: 8rem;
  overflow-y: auto;
  color: var(--text);
  background: var(--panel);
  border-color: var(--border);
}

.checklist-necessity {
  flex: 0 0 auto;
  width: auto;
  font-size: 0.8rem;
  padding: 0.3rem 0.5rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font-weight: 600;
  cursor: pointer;
}

.necessity-definite {
  background: rgba(107, 15, 26, 0.12);
  color: var(--accent);
  border-color: rgba(107, 15, 26, 0.3);
}

.necessity-possible {
  background: rgba(212, 175, 55, 0.16);
  color: var(--text);
  border-color: rgba(212, 175, 55, 0.45);
}

.necessity-optional {
  background: var(--bg);
  color: var(--muted);
  border-color: var(--border);
}

.checklist-status {
  flex: 0 0 auto;
  width: auto;
  font-size: 0.8rem;
  padding: 0.3rem 0.5rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font-weight: 600;
  cursor: pointer;
}

.status-not-started {
  background: var(--bg);
  color: var(--muted);
  border-color: var(--border);
}

.status-in-progress {
  background: rgba(212, 175, 55, 0.16);
  color: var(--text);
  border-color: rgba(212, 175, 55, 0.45);
}

.status-done {
  background: rgba(26, 122, 68, 0.14);
  color: var(--ok);
  border-color: rgba(26, 122, 68, 0.35);
}

/* Masonry via CSS columns rather than a uniform grid -- photos keep their
   natural aspect ratio (no cropping) and different heights sit side by
   side, which reads more like a scrapbook than an admin table. */
.memory-gallery {
  column-count: 3;
  column-gap: 1.25rem;
}

@media (max-width: 900px) {
  .memory-gallery { column-count: 2; }
}

@media (max-width: 600px) {
  .memory-gallery { column-count: 1; }
}

.memory-tile {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin: 0 0 1.25rem;
  overflow: hidden;
  break-inside: avoid;
  cursor: pointer;
  transition: transform 0.15s, box-shadow 0.15s;
}

.memory-tile:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}

.memory-tile img,
.memory-tile video {
  display: block;
  width: 100%;
  height: auto;
  background: var(--bg);
}

.memory-tile figcaption {
  padding: 0.6rem 0.75rem;
  font-size: 0.85rem;
}

.memory-tile figcaption strong {
  font-family: Georgia, "Times New Roman", serif;
}

.memory-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 140px;
  color: var(--muted);
  font-size: 0.85rem;
  text-align: center;
  padding: 0.5rem;
}

/* Lightbox: click any tile to view it full-size with its story (name,
   date, message) rather than squinting at a masonry thumbnail. */
.lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(10, 8, 6, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 3rem 4.5rem;
}

.lightbox-overlay[hidden] { display: none; }

.lightbox-content {
  max-width: 100%;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}

.lightbox-media {
  max-width: 100%;
  max-height: 72vh;
  display: flex;
}

.lightbox-media img,
.lightbox-media video {
  max-width: 100%;
  max-height: 72vh;
  border-radius: 8px;
  display: block;
}

.lightbox-caption {
  color: #f2efe9;
  text-align: center;
  max-width: 38rem;
}

.lightbox-caption strong {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.15rem;
}

.lightbox-caption .hint {
  color: #b8b3a8;
  display: block;
  margin-top: 0.15rem;
}

.lightbox-caption p {
  margin: 0.6rem 0 0;
  line-height: 1.5;
}

.lightbox-close,
.lightbox-nav {
  position: absolute;
  background: transparent;
  border: none;
  color: #f2efe9;
  cursor: pointer;
  line-height: 1;
}

.lightbox-close {
  top: 1rem;
  right: 1.25rem;
  font-size: 2.2rem;
}

.lightbox-nav {
  top: 50%;
  transform: translateY(-50%);
  font-size: 3rem;
  padding: 0.5rem 0.75rem;
}

.lightbox-prev { left: 0.5rem; }
.lightbox-next { right: 0.5rem; }

.lightbox-close:hover,
.lightbox-nav:hover { opacity: 0.75; }

@media (max-width: 700px) {
  .lightbox-overlay { padding: 1.5rem 1rem; }
  .lightbox-nav { font-size: 2.2rem; }
}

.checklist-item.done .checklist-title {
  text-decoration: line-through;
  color: var(--muted);
}

.checklist-item button {
  flex-shrink: 0;
}

.inbox-message {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.6rem 1rem;
  margin-bottom: 0.5rem;
}

.inbox-message.unread {
  border-color: var(--accent);
  background: rgba(107, 15, 26, 0.05);
}

.inbox-message-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  flex-wrap: wrap;
  cursor: pointer;
}

.inbox-message-from {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.unread-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
}

.inbox-message-snippet {
  margin-top: 0.3rem;
  cursor: pointer;
}

.inbox-message-body {
  white-space: pre-wrap;
  font-size: 0.9rem;
  color: var(--text);
  margin-top: 0.5rem;
}

.inbox-reply {
  margin-top: 0.6rem;
  padding: 0.5rem 0.75rem;
  border-left: 3px solid var(--accent-2);
  background: rgba(212, 175, 55, 0.08);
  border-radius: 0 6px 6px 0;
}

.inbox-reply-form {
  margin-top: 0.75rem;
  padding-top: 0.6rem;
  border-top: 1px dashed var(--border);
}

.inbox-reply-form textarea {
  min-height: 60px;
  margin-bottom: 0.4rem;
}

.link-icons {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding-top: 0.35rem;
}

.link-icon {
  flex-shrink: 0;
  text-decoration: none;
  font-size: 0.95rem;
  line-height: 1;
}
