/* Copyright (c) 2026 Goldeneye Technologies LLC. All rights reserved. */
/**************************************************************************/
/********     Global classes          *************************************/
/**************************************************************************/
html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
  line-height: var(--line-height-base);
  color: var(--color-text);
  background-color: var(--color-bg);
  /* Pin text at its authored size so iOS Safari doesn't auto-inflate it on a
     portrait->landscape rotation and leave it enlarged when rotating back
     (observed on the footer, whose height then grew and stayed grown). We set
     every font-size explicitly via tokens, so the browser's auto text-sizing
     is unwanted everywhere. <JAS 2026-07-16> */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
#main {width:100%; height:100%;}
#content {width:100%; height:97.5%;}
#footer {
  width: 100%;
  height: 2.5%;
  background-color: var(--color-bg-muted);
  border-top: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
}
#footer_content {padding: 0 var(--space-4);}
#footer a {
  color: var(--color-accent);
  text-decoration: underline;
}
#footer a:hover {color: var(--color-accent-hover);}
.main_unpinned {
  position: relative;
  left: 2.5%;
  width: 97.5%;
  height: 100%;
  /* NO z-index — deliberately. `position: relative; z-index: 0` here formed a
     STACKING CONTEXT around the entire page, which meant no z-index declared
     inside #content_main could ever be compared against the body-level chrome
     (`#sidenav_hamburger`, `#sidenav_backdrop`, `#content_sideNav`). The whole
     page painted as one unit at z-index 0, so the hamburger (1400) covered the
     chart overlay (2000) and the info panel (1200) even though their numbers
     say otherwise, while `#data_table_overlay` — the one modal that is appended
     to <body> rather than living in the template — escaped and behaved
     correctly. That inconsistency is what made the layering look arbitrary.

     Note this rule was the context in BOTH pin states: `_apply_nav_pin`
     (nav/toggle.js) ADDS `main_pinned` without removing `main_unpinned`, so the
     element carries both and only `left`/`width` are actually overridden.
     Deleting the declaration here therefore removes the context everywhere,
     which is the intent — there is no second source to chase.

     Why that is safe: #content_main stays `position: relative`
     (it is the containing block for the map column), nothing inside it uses a
     negative z-index that would now fall behind the page background, and the
     mobile footer's
     `position: relative; z-index: 1` in the block below still outranks it —
     an explicit z-index beats a positioned `z-index: auto` element regardless
     of DOM order — so that fix is untouched. See tokens.css for the resulting
     layer scale. <JAS 2026-08-21> */
  transition: 0.5s;
}

/* NOTE: This is not quite correct, but works for development.
   <JAS 2025-06-13>
*/
/* Pinned offset is a fixed 180px to match the fixed-width pinned side-nav
   (content_sideNav.css `.sidenav_pinned { width: 180px }`); the two must stay in
   lockstep so the content sits flush against the nav. <JAS 2026-06-22> */
.main_pinned {position: relative; left: 180px; width: calc(100% - 180px);}

/**************************************************************************/
/********     Content pages           *************************************/
/**************************************************************************/
#content_main.main_scrollable {overflow-y: auto;}

.content-page {
  max-width: 720px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-4) var(--space-8);
  color: var(--color-text);
}
.content-page h1 {
  font-size: var(--font-size-2xl);
  line-height: var(--line-height-tight);
  font-weight: var(--font-weight-semibold);
  margin: 0 0 var(--space-4);
}
.content-page h2 {
  font-size: var(--font-size-xl);
  line-height: var(--line-height-tight);
  font-weight: var(--font-weight-semibold);
  margin: var(--space-6) 0 var(--space-2);
}
.content-page p {
  line-height: var(--line-height-base);
  margin: 0 0 var(--space-3);
}
.content-page a {
  color: var(--color-accent);
  text-decoration: underline;
}
.content-page a:hover {color: var(--color-accent-hover);}
.content-page code {
  background: var(--color-bg-muted);
  padding: 0 var(--space-1);
  border-radius: var(--radius-sm);
  font-family: var(--font-family-mono);
  font-size: var(--font-size-sm);
}

.feedback-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-top: var(--space-3);
}
.feedback-form label {
  margin-top: var(--space-3);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}
.feedback-form label .optional {
  font-weight: var(--font-weight-regular);
  color: var(--color-text-muted);
}
.feedback-form input[type=text],
.feedback-form input[type=email],
.feedback-form textarea {
  width: 100%;
  padding: var(--space-2);
  box-sizing: border-box;
  font: inherit;
  color: var(--color-text);
  background-color: var(--color-bg-elevated);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  transition: border-color var(--transition-base), box-shadow var(--transition-base);
}
.feedback-form input[type=text]:focus,
.feedback-form input[type=email]:focus,
.feedback-form textarea:focus {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px var(--color-focus-ring);
}
/* Suppress the default browser outline only on non-keyboard focus; the
   global :focus-visible rule paints the canonical a11y outline on top
   of the box-shadow ring above for keyboard users. */
.feedback-form input[type=text]:focus:not(:focus-visible),
.feedback-form input[type=email]:focus:not(:focus-visible),
.feedback-form textarea:focus:not(:focus-visible) {
  outline: none;
}
.feedback-form textarea {resize: vertical;}
.feedback-form button {
  margin-top: var(--space-4);
  padding: var(--space-2) var(--space-4);
  cursor: pointer;
  font: inherit;
  font-weight: var(--font-weight-medium);
  background: var(--color-accent);
  color: var(--color-text-inverse);
  border: 0;
  border-radius: var(--radius-sm);
  align-self: flex-start;
  transition: background-color var(--transition-base);
}
.feedback-form button:hover {background: var(--color-accent-hover);}
/* Pre-fill context banner shown when arriving from the map context menu's
   "Send Feedback About this Location" item (lat/lon + optional symbol). */
.feedback-location-note {
  margin-top: var(--space-3);
  padding: var(--space-2) var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-info-text);
  background: var(--color-info-bg);
  border-radius: var(--radius-sm);
}
.feedback-location-note p:last-child {margin-bottom: 0;}
/* The map values inside that banner, rendered as SELECTABLE text (batch-8 A8).
   With no database the location travels by email, so a visitor with no mail
   client has to be able to copy the symbol and coordinates by hand — the
   `mailto:` is the convenience, this is the guarantee. */
.feedback-context {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-1) var(--space-3);
  margin: var(--space-2) 0 0;
}
.feedback-context dt {
  font-weight: var(--font-weight-semibold);
}
.feedback-context dd {
  margin: 0;
}
/* Reassurance note under the optional contact-email field: states the
   narrow purpose + retention limit (privacy/ToS groundwork). */
.feedback-privacy-note {
  margin-top: var(--space-2);
  font-size: var(--font-size-xs);
  line-height: var(--line-height-base);
  color: var(--color-text-muted);
}

/* ----------------------------------------- */
/* Mobile viewport (≤ 768 CSS px wide). Tighten the long-form content-page
   gutters and grow the feedback-form controls to the 44px touch-target
   minimum (WCAG 2.5.5). `font-size: 16px` on the text fields suppresses iOS
   Safari's focus auto-zoom (it zooms any control with a sub-16px font on
   focus). Additive only — the desktop metrics above are untouched (Lane E /
   Prompt 4). <JAS 2026-06-22> */
/* ----------------------------------------- */
@media (max-width: 768px),
       (orientation: landscape) and (max-height: 500px) and (pointer: coarse) {
  .content-page {
    padding: var(--space-4) var(--space-4) var(--space-6);
  }
  /* The fixed top-left nav hamburger (48px square at an 8px inset → right edge
     56px) overlaps the first line of the page title on content + feedback
     pages. Indent the <h1> clear of it. padding-left applies to all wrapped
     lines, so a multi-line title reads as a consistent hanging offset rather
     than colliding with the button. Was 52px for a nominal 44px button, which
     under-cleared by 20px while that button was rendering 64px wide (the
     content-box bug fixed in content_sideNav.css 2026-08-21). <JAS 2026-08-21> */
  .content-page h1 {
    padding-left: 56px;
  }
  .feedback-form input[type=text],
  .feedback-form input[type=email],
  .feedback-form textarea,
  .feedback-form button {
    min-height: 44px;
    font-size: 16px;
  }
  /* Let the message box start at a comfortable multi-line height rather than
     the 44px single-row floor (it stays user-resizable). */
  .feedback-form textarea {
    min-height: 120px;
  }

  /* Footer height on mobile (round-2 feedback). The desktop footer is a fixed
     2.5%-tall strip; on a phone its long legal/links line wraps to two lines that
     the 2.5% height can't contain, so the lines overlap the page content above.
     Make #main a flex column so the footer takes its natural (auto) height and
     #content fills the rest. The map page is unaffected visually — its map is a
     positioned full-viewport layer that ignores #content's height, and the footer
     there sits behind it (see the map-page note below). <JAS 2026-06-22> */
  #main {
    display: flex;
    flex-direction: column;
  }
  #content {
    height: auto;
    flex: 1 1 auto;
    min-height: 0;
  }
  #footer {
    height: auto;
    flex: 0 0 auto;
    padding: var(--space-2) var(--space-3);
    /* Lift the footer above #content_main's stacking context (round-3 feedback).
       #content_main is `position: relative; z-index: 0` (main_unpinned), which
       paints it ABOVE the static footer — the footer then read as "see-through"
       with the page content overlapping it and the overlay layer intercepting
       clicks on its links. A positioned footer with z-index:1 + the
       opaque --color-bg-muted surface keeps it on top and clickable; the scroll
       fix below stops the overlap at the source. <JAS 2026-06-22> */
    position: relative;
    z-index: 1;
  }
  #footer_content {
    text-align: center;
    line-height: var(--line-height-base);
  }
  /* Constrain the scrollable content column so it can't overflow its flex box and
     paint over the footer (round-3 feedback). The round-2 fix made #main a flex
     column (footer = auto height), but #content_main still relied on a percentage
     height (main_unpinned `height: 100%`) that didn't reliably resolve here, so it
     grew to full content height and spilled past #content onto the footer. Make
     #content a flex column and let #content_main be the flex child that scrolls
     INTERNALLY (its overflow-y:auto, set via main_scrollable, needs a resolved
     height to engage). Now the last content scrolls fully into view above the
     footer — no manual bottom offset needed. The map page (#content_main without
     main_scrollable) is unaffected: its .map is an absolute full-viewport layer
     that ignores this flow. <JAS 2026-06-22> */
  #content {
    display: flex;
    flex-direction: column;
  }
  #content_main.main_scrollable {
    height: auto;
    flex: 1 1 auto;
    min-height: 0;
  }
}

/**************************************************************************/
/********     Flash messages          *************************************/
/**************************************************************************/
.flash-region {
  max-width: 720px;
  margin: var(--space-3) auto 0;
  padding: 0 var(--space-4);
}
.flash {
  margin: 0 0 var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-sm);
}
.flash.error   {background: var(--color-error-bg);   color: var(--color-error-text);}
/* Info flashes (logout, selection-cap, runtime notices) use the Tickerscape
   brand teal to match the campaign banner; white-on-accent is AA 6.2:1. Error
   stays red / success stays green (semantic). <JAS 2026-06-26> */
.flash.info    {background: var(--color-accent);     color: var(--color-text-inverse);}
.flash.success {background: var(--color-success-bg); color: var(--color-success-text);}
/* Body-level flash TOASTS (map page: modules/notice.js + the re-homed server
   flash in flash.js) carry a `flash--{cat}` modifier instead of the bare
   `info`/`error`/`success` category class. The bare `.info` token collides with
   the info-panel layout class (`content_infoPanel.css .info` — height:100% /
   float / mobile bottom-sheet), which stretched the fixed toast to full viewport
   height once it lived on <body>. Same colours as the `.flash.{cat}` rules above;
   the in-flow content-page flashes keep the original `.flash.{cat}` classes.
   <JAS 2026-06-26> */
.flash--info    {background: var(--color-accent);     color: var(--color-text-inverse);}
.flash--error   {background: var(--color-error-bg);   color: var(--color-error-text);}
.flash--success {background: var(--color-success-bg); color: var(--color-success-text);}

/**************************************************************************/
/********     Accessibility — focus indicators + skip link    *************/
/**************************************************************************/
/* Global keyboard focus indicator (consumes --color-focus-ring). Uses
   :focus-visible so mouse clicks don't paint rings; composes alongside
   the per-component box-shadow rules (feedback form, search input)
   without conflict — outline and box-shadow are independent layers. */
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
a:focus-visible,
[role="button"]:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
  outline: 3px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/* Skip-to-main-content link (Step 2). Off-screen until :focus reveals
   it at the top-left. Tab is the only way to surface this control. */
.skip-link {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 10000;
  padding: var(--space-2) var(--space-3);
  background: var(--color-bg-elevated);
  color: var(--color-text);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-md);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
  transform: translateY(-150%);
  transition: transform var(--transition-base);
}
.skip-link:focus { transform: translateY(0); }

/* Respect prefers-reduced-motion (WCAG 2.3.3 / 2.1 AA-adjacent best practice).
   Collapse CSS transitions + animations to near-instant so the chrome motions
   stop animating: token-driven hover transitions (--transition-base), the
   sidenav expand / info-panel collapse / layout-shift 0.5s slides, and
   Leaflet's pan/zoom glides (its inline transition-duration is overridden, so
   the map snaps instead of gliding — preferred for vestibular sensitivity).
   The per-tick MARKER recolor/resize/reshape has no CSS transition (discrete
   JS repaints), so it is attenuated separately in main.js by throttling the
   restyle cadence under reduced motion. <JAS 2026-06-12> */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Screen-reader-only utility: keeps content in the accessibility tree (and
   the document outline) while removing it visually. Used for the map page's
   <h1>, where a visible heading would clutter the full-bleed map. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   "Tickerscape Verified" badge (batch-5 P9). Site-wide because two surfaces
   render it: the info-panel card (built in JS by
   info_panel/locations.js::render_verification_badge) and the server-rendered
   ticker page (html/_verification_badge.html macro). One definition, so the two
   cannot drift visually.

   The badge is a LINK into the /methodology definition, so it inherits the
   global :focus-visible ring and is keyboard-reachable. State is carried by the
   label TEXT and the glyph SILHOUETTE (check / warning triangle / circled "i");
   colour is enhancement only, never the sole channel — the decode-without-
   colour a11y contract. <JAS 2026-08-12>
   --------------------------------------------------------------------------- */
.ts-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  max-width: 100%;
  padding: 1px var(--space-2) 1px var(--space-1);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-xs);
  line-height: var(--line-height-tight);
  color: var(--color-text-muted);
  text-decoration: none;
}
.ts-badge:hover {
  background-color: var(--color-bg-hover);
}
.ts-badge-icon {
  flex: 0 0 14px;
  height: 14px;
  width: 14px;
}
/* The label may be clipped in the narrow info panel; the accessible name and
   the tooltip carry the full sentence either way. */
.ts-badge-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ts-badge-date {
  flex: 0 0 auto;
}
.ts-badge-verified {
  color: var(--color-accent);
  border-color: var(--color-accent);
}
.ts-badge-verified:hover {
  color: var(--color-accent-hover);
}
/* Amber-brown rather than a warning red: this state says "the filing gives a
   different KIND of address", not "this is an error" — the label and glyph were
   made non-judgemental on 2026-09-07 and the colour must not put the verdict
   back. AA on the light card surface. */
.ts-badge-filed {
  color: #8a5300;
  border-color: #8a5300;
}
