/* =============================================================================
   KilusNa — SHARED AUTHENTICATED STATE (?auth=1) — auth-state.css
   -----------------------------------------------------------------------------
   Extracted VERBATIM from publication.css so index.html and publication.html
   share one copy of the logged-in chrome; publication.css keeps only what is
   detail-page specific (follow, disputes, composer, claim pill, gallery).
   This file also carries the homepage-only auth additions (panel-header
   CTAs, the Verified Member badge, interactive vote rails).

   State model: the head bootstrap reads ?auth=1 and sets html.is-auth before
   any paint. Logged-in-only markup carries .auth-only, guest affordances
   .guest-only.

   Consumes ONLY tokens.css — zero hardcoded hex anywhere in this file.

   Load order (part of the spec): tokens → base → layout → components →
   page → mobile → auth-state → dark. Loading AFTER mobile.css matters:
   mobile.css re-shows .header-actions .btn at ≥640 with specificity
   (0,2,0), and the html.is-auth rules below are (0,2,1) — they win by
   specificity AND by cascade order, so no !important is ever needed.
   ============================================================================= */

/* ===== State swap ==========================================================
   The head bootstrap reads ?auth=1 and sets html.is-auth before any paint.
   Logged-in-only markup carries .auth-only, guest affordances carry
   .guest-only. Both selectors (0,2,1) outrank the component defaults
   (0,1,0) so no !important is needed, and the logged-out render is
   untouched: .auth-only nodes simply never display. */
html:not(.is-auth) .auth-only { display: none; }
html.is-auth .guest-only { display: none; }

/* --- header identity cluster (live order: Admin → bell → Messages →
       profile → Logout) ---------------------------------------------------- */
.header-notif { position: relative; }

/* Responsive collapse: the FULL cluster needs ~670px of row (Admin btn +
   bell + Messages + named profile + Logout + theme). Below 1024 the drawer
   already carries Admin Panel / Messages / My Profile, so the header sheds
   them there and keeps the two controls that have no drawer equivalent:
   the notifications bell and Logout. The avatar survives (its /profile/
   target is in the drawer, but the face is the identity anchor). Width at
   1023: menu 44 + logo 80 + theme 44 + bell 44 + avatar 36 + Logout ~48
   + gaps ≈ 340 < 1023 — comfortable at every width down to 360.
   The html.is-auth prefix is load-bearing: mobile.css re-shows every
   .header-actions .btn at ≥640 with specificity (0,2,0) — this selector
   (0,2,1) outranks it without !important (and this file loads after
   mobile.css, so the cascade agrees too). */
@media (max-width: 1023px) {
  html.is-auth .header-admin,
  html.is-auth .header-messages,
  html.is-auth .auth-profile-name { display: none; }

  html.is-auth .auth-profile { padding: 0 var(--s1); }
}

.notif-btn { position: relative; }   /* .icon-btn already supplies 44×44 */

/* Count chip: the .section-count plate recipe on a small disc —
   accent-text on accent-soft reads 5.38:1 light / 9.14:1 dark; the 2px
   --card halo keeps the disc legible over the bell glyph in both themes.
   Shown even at 0 so the component is reviewable (live hides it at 0 —
   flagged as a deliberate delta in the delivery notes). */
.notif-count {
  position: absolute;
  top: 2px;
  right: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  background: var(--accent-soft);
  border: 2px solid var(--card);
  border-radius: var(--r-pill);
  color: var(--accent-text);
  font-size: var(--fs-tiny);
  font-weight: 700;
  line-height: 1;
}

/* Bell dropdown — a real dialog (role=dialog + aria-label in markup):
   card plate + popup shadow, right-anchored to the bell. ≤480 it becomes a
   viewport-anchored sheet (see the ≤480 block) so it can never hang off a
   360px viewport edge. Hiding is the markup's [hidden] attribute
   (components.css rule). */
.notif-dropdown {
  position: absolute;
  top: calc(100% + var(--s2));
  right: 0;
  z-index: 60;                   /* same band as the header search dropdown */
  min-width: 300px;
  max-width: calc(100vw - var(--s6));
  max-height: min(60vh, 420px);
  overflow-y: auto;
  padding: var(--s3);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-pop);
}

.notif-dropdown-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
  margin-bottom: var(--s2);
}

.notif-dropdown-header h2 {
  font-size: var(--fs-title);
  font-weight: 700;
  color: var(--text);
}

.notif-mark-read {
  min-height: 44px;
  padding: 0 var(--s2);
  border-radius: var(--r-btn);
  color: var(--accent-text);      /* 5.93:1 on --card light / 12.06:1 dark */
  font-size: var(--fs-sm);
  font-weight: 600;
  transition: background .15s ease;
}

.notif-mark-read:hover { background: var(--accent-soft); }

.notif-list { display: flex; flex-direction: column; }

.notif-empty {
  padding: var(--s3) 0;
  font-size: var(--fs-sm);
  color: var(--muted);
  text-align: center;
}

/* Messages / Logout: text-weight header actions, 44px targets */
.header-text-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--s2);
  border-radius: var(--r-btn);
  color: var(--body);
  font-size: var(--fs-sm);
  font-weight: 600;
  transition: background .15s ease, color .15s ease;
}

.header-text-link:hover { background: var(--accent-soft); color: var(--accent-text); }

/* Profile badge: avatar disc + username, both inside a 44px pill */
.auth-profile {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  min-height: 44px;
  padding: 0 var(--s2) 0 var(--s1);
  border-radius: var(--r-pill);
  transition: background .15s ease;
}

.auth-profile:hover { background: var(--hover); }

.auth-profile-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  background: var(--accent-soft);
  border-radius: 50%;
  color: var(--accent-text);
}

.auth-profile-avatar svg { width: 16px; height: 16px; }

.auth-profile-name {
  max-width: 14ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: 600;
}

/* Drawer's Verified account row: green marker — --green reads 5.02:1 on
   --card light and 11.55:1 on --card dark. Hover uses the system's
   universal link recipe (accent-soft/accent-text, 5.38:1) rather than
   green-on-green-soft (~4.50:1 — passes, but with no margin); the green
   at rest still carries the verification semantic where it is actually
   read. */
.sidebar-nav-verified { color: var(--green); }
.sidebar-nav-verified svg { color: var(--green); }

/* --- Reaction / Save pressed state (auth-only) ----------------------------
   The .section-count plate recipe again. aria-pressed is the single
   source of truth (live styles an .active class; styling from the ARIA
   state keeps the DOM state and the visual state from ever diverging).
   The guest render never sets aria-pressed, so logged-out output is
   byte-identical. */
.eng-react[aria-pressed="true"],
.react-btn.bookmark[aria-pressed="true"] {
  background: var(--accent-soft);
  color: var(--accent-text);
}

/* ===== Homepage additions (index.html?auth=1) ============================= */

/* --- Panel-header CTAs (Reports "+ New Report" / Pending Review "+ Submit
       Report" / Petitions "+ Start a petition") ---------------------------
   .panel-header is a column, so a .btn child would stretch to full width;
   align-self keeps it its natural size, with the same 6px + 8px rhythm the
   Discussions panel's .panel-header-actions uses. This rule never sets
   display, so the state swap above stays the only thing that shows or
   hides the CTA. */
.panel-header > .btn.auth-only {
  align-self: flex-start;
  margin-top: var(--s2);
}

/* --- Verified badge (left-rail CTA pill + sidebar status row) -------------
   The comment card's NOTES §1 tone-badge construction, reused here so the
   prototype speaks one badge language: semantic colour on the border and
   icon, the label stays --text (16.3–17.0:1 light / 12.5–13.7:1 dark on
   the tone plate). Tokens only — green / green-soft resolve per theme with
   no dark override. */
.auth-verified-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  background: var(--green-soft);
  border: 1px solid var(--green);
  border-radius: var(--r-pill);
  color: var(--text);
  font-size: var(--fs-badge);
  font-weight: 700;
  line-height: 1.5;
}

.auth-verified-badge svg { width: 13px; height: 13px; color: var(--green); }

/* The sidebar's verified row is a status pill, not a link (home-auth.html
   renders it as a non-link row): suppress the link affordance so a hover
   plate never implies it can be clicked, and keep the text selectable. */
.sidebar-nav-link.sidebar-verified-badge { cursor: default; }

.sidebar-nav-link.sidebar-verified-badge:hover {
  background: transparent;
  color: var(--body);
}

/* --- Vote rails (auth-only interactivity) ---------------------------------
   Guest cards keep the display-only 24×22 carets untouched — every rule
   below is html.is-auth-scoped, so a logged-out card never sees it. In
   auth mode auth-state.js promotes each caret to a toggle control
   (role=button + tabindex + aria-pressed) and this block gives it the
   44×44 hit area master-prompt requires via a transparent overlay centred
   on the glyph. The rail gap opens to 16px so neither overlay can reach
   the count between them (overlay overhang is 11px per side) or the
   other caret (centres sit ~70px apart, well beyond 44).
   Pressed state = the .section-count plate recipe (accent-text on
   accent-soft, 5.38:1 light / 9.14:1 dark) — the same plate publication
   gives its own downvote, so "on" never changes meaning with direction,
   and the plate's appearance is a shape cue on top of colour (WCAG 1.4.1). */
html.is-auth .content-panel .vote { gap: var(--s4); }

html.is-auth .content-panel .vote-icon {
  position: relative;
  cursor: pointer;
  /* components.css transitions colour only — the pressed plate needs the
     same background fade the .react-btn plates have */
  transition: background .12s ease, color .12s ease;
}

html.is-auth .content-panel .vote-icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}

html.is-auth .content-panel .vote-icon[aria-pressed="true"] {
  background: var(--accent-soft);
  color: var(--accent-text);
  border-radius: var(--r-btn);
}

/* Bookmark pressed: the plate comes from the shared rule above; the glyph
   also fills in, so the saved state changes SHAPE as well as colour
   (WCAG 1.4.1) — the accessible name swaps too (auth-state.js). */
html.is-auth .content-panel .react-btn.bookmark[aria-pressed="true"] svg {
  fill: currentColor;
}

/* ===== Breakpoints ======================================================== */
/* ≤480 — the surviving cluster would only fit a 360px row by shrinking
   the hamburger below its 44px target (header-actions is flex-shrink:0),
   so the avatar drops too — bell + Logout + theme remain, and the drawer
   carries My Profile exactly as the approved collapse allows. */
@media (max-width: 480px) {
  .header-text-link { padding: 0 var(--s1); }
  html.is-auth .auth-profile { display: none; }

  /* dropdown becomes a viewport-anchored sheet so it can never hang off
     the right edge when the bell sits near it */
  .notif-dropdown {
    position: fixed;
    top: calc(var(--header-h) + var(--s2));
    right: var(--s4);
    left: var(--s4);
    min-width: 0;
    max-width: none;
  }
}

/* ≤647 — master-prompt type floor (mobile.css bumps the shared classes;
   the auth-only classes below are new, so they get their floor here). */
@media (max-width: 647px) {
  .header-text-link,
  .auth-profile-name,
  .notif-mark-read { font-size: 16px; }

  .notif-empty { font-size: 16px; }
  .notif-dropdown-header h2 { font-size: 17px; }
}
