:root {
  /* Brand palette — extracted directly from the TrueNorth logo (compass
     ring/wordmark navy, needle/"North" gold, logo backing cream, tagline
     gray). Kept under the original token names used throughout this file
     to avoid a second, parallel set of color variables. */
  --navy: #0f1f3d;
  --navy-light: #193664;
  --gold: #c9962f;
  --gold-light: #d9ac55;
  /* --gold itself only passes WCAG AA text contrast (4.5:1) against the
     navy header background (6.14:1 there) -- against the white/cream card
     backgrounds it's used as TEXT on (link-style buttons: disclaimer
     toggle, watchlist/financial toggles, Terms link, auth switch links,
     etc.), it only reaches ~2.4-2.7:1. This darker variant is for exactly
     those text-on-light-background cases; --gold itself is unchanged and
     still correct for anything on the navy header/nav. Same darkening
     already applied to --warn-text/--score-below-text below, which are
     this same gold family lightened into a bg + darkened into a text
     color, at ~5.2:1 -- gold-text matches that established pattern rather
     than inventing a new one. */
  --gold-text: #8a6008;
  --bg: #f5f1e8;
  --card-bg: #ffffff;
  --text: #1c2530;
  --muted: #6b675c;
  --border: #e1ddd3;
  --success-bg: #e6f2ea;
  --success-text: #1e6b3e;
  --warn-bg: #fbf1de;
  --warn-text: #8a5a12;
  --danger-bg: #fbeaea;
  --danger-text: #a3312c;
  --neutral-bg: #ececea;
  --neutral-text: #5c6773;
  --score-above-bg: #cdead9;
  --score-above-text: #145c37;
  --score-average-bg: #e9f6ef;
  --score-average-text: #2f6b4d; /* darkened from #4c9270 -- the original only hit 3.34:1 against its own bg, below WCAG AA's 4.5:1 for text; this hits 5.67:1, in line with --score-above-text/--success-text's own contrast against their similar backgrounds */
  --score-below-bg: #fdf3b8;
  --score-below-text: #7a6300;
  --font-serif: Georgia, 'Times New Roman', Times, serif;
  --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
}

* {
  box-sizing: border-box;
}

img {
  max-width: 100%;
  height: auto;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -3rem;
  left: 0.75rem;
  z-index: 100;
  background: var(--navy);
  color: #fff;
  padding: 0.6rem 1rem;
  border-radius: 0 0 6px 6px;
  font-weight: 600;
  text-decoration: none;
  transition: top 0.15s ease;
}

.skip-link:focus {
  top: 0;
}

.global-error-banner {
  position: fixed;
  left: 1rem;
  right: 1rem;
  bottom: 1rem;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: 560px;
  margin: 0 auto;
  background: var(--danger-bg);
  color: var(--danger-text);
  border: 1px solid #eecfcd;
  border-radius: 8px;
  padding: 0.85rem 1rem;
  box-shadow: 0 4px 16px rgba(15, 31, 61, 0.18);
}

.global-error-banner p {
  margin: 0;
  font-size: 0.88rem;
}

.global-error-banner button {
  flex-shrink: 0;
  background: none;
  border: none;
  color: var(--danger-text);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 0.15rem;
}

.back-to-top-btn {
  position: fixed;
  right: 1.25rem;
  bottom: 1.5rem;
  z-index: 80;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  border: none;
  background: var(--navy);
  color: #fff;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(15, 31, 61, 0.28);
}

.back-to-top-btn:hover {
  background: var(--navy-light);
}

.download-toast {
  position: fixed;
  left: 1rem;
  bottom: 1.25rem;
  z-index: 92;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  max-width: 320px;
  background: var(--navy);
  border-radius: 8px;
  padding: 0.55rem 0.5rem 0.55rem 0.9rem;
  box-shadow: 0 6px 20px rgba(15, 31, 61, 0.35);
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity 0.2s ease,
    transform 0.2s ease;
  pointer-events: none;
}

.download-toast.visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

@media (max-width: 480px) {
  .download-toast {
    left: 0.75rem;
    right: 0.75rem;
    max-width: none;
  }
}

.download-toast-open {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
  border: none;
  background: none;
  color: #fff;
  cursor: pointer;
  padding: 0.2rem 0;
  text-align: left;
}

.download-toast-icon {
  flex: none;
  width: 20px;
  height: 20px;
  color: var(--gold-light);
}

.download-toast-icon svg {
  width: 100%;
  height: 100%;
}

.download-toast-filename {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: underline;
}

.download-toast-close {
  flex: none;
  border: none;
  background: none;
  color: rgba(255, 255, 255, 0.7);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
}

.download-toast-close:hover {
  color: #fff;
}

.offline-banner {
  position: fixed;
  left: 1rem;
  right: 1rem;
  bottom: 1rem;
  z-index: 90;
  max-width: 560px;
  margin: 0 auto;
  background: var(--warn-bg);
  color: var(--warn-text);
  border: 1px solid #f0dfb8;
  border-radius: 8px;
  padding: 0.7rem 1rem;
  text-align: center;
  box-shadow: 0 4px 16px rgba(15, 31, 61, 0.18);
}

.offline-banner p {
  margin: 0;
  font-size: 0.88rem;
}

.site-header {
  background: var(--navy);
  padding: 0.85rem 1.5rem;
}

/* Grid (not flex) so the centered title (.site-header-title) sits in the
   remaining space between the logo and the nav actions regardless of
   either side's own width, rather than needing absolute positioning that
   could overlap them on narrow screens. */
.site-header-inner {
  max-width: 900px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1rem;
}

/* 2026-08-25: the header's own "large text in the middle of the strip" --
   replaces the earlier standalone hero card below the header (removed)
   with a lighter-weight brand moment built directly into the persistent
   navy strip instead. Matches the wordmark's own navy/gold pairing from
   the logo image, just inverted for a dark background (light "True",
   gold "North") since this sits on --navy rather than the logo's own
   cream backing. Purely decorative -- the logo link's own aria-label
   already names "TrueNorth home" for assistive tech. */
.site-header-title {
  margin: 0;
  text-align: center;
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 1.7rem;
  letter-spacing: 0.01em;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.site-header-title-accent {
  color: var(--gold-light);
}

@media (max-width: 640px) {
  .site-header-title {
    font-size: 1.15rem;
  }
}

@media (max-width: 420px) {
  .site-header-title {
    font-size: 0.95rem;
  }
}

/* Account widget — Log In/Log Out (plus Delete Account once signed in),
   the account-lifecycle controls that stay visible at every screen width,
   unlike the hamburger menu itself (see .hamburger-dropdown below for
   everything else, including the signed-in email), which is hidden
   outright at >=720px. Empty (no markup) until Firebase resolves the first
   auth check, and permanently empty if Firebase never loaded — see
   auth.js/renderAccountWidget. */
.account-widget {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.account-widget-link {
  border: none;
  background: none;
  color: var(--gold-light);
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
  padding: 0;
  white-space: nowrap;
}

.account-widget-link:hover {
  text-decoration: underline;
  color: #fff;
}

.account-widget-link-danger {
  color: #e39a95;
}

.account-widget-link-danger:hover {
  color: #fff;
}

/* Groups the hamburger nav menu and the account widget together on the
   right side of the header, so justify-content: space-between on
   .site-header-inner only ever splits "logo" from "everything else"
   regardless of how many items are in this group. Also anchors the
   hamburger dropdown (position: relative) -- deliberately here rather than
   on .site-nav-menu itself, so the dropdown's `right: 0` aligns to this
   whole group's right edge (reliably near the header's own right edge via
   justify-content: flex-end below) instead of to the hamburger button,
   whose own position shifts leftward as its sibling account-widget links
   (Log Out, Delete Account) grow wider -- on a narrow phone screen that
   shift was enough to push a button-anchored dropdown off the left edge
   of the viewport entirely. */
.site-header-actions {
  position: relative;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* Hamburger nav menu — 2026-08-25, replaced the old flat "Ticker Tester"
   text link plus My Portfolios/My Watchlist inside the account widget
   with one menu covering all four features (see renderSiteNavMenu,
   app.js). No positioning of its own -- see .site-header-actions above for
   where the dropdown is actually anchored. */

.hamburger-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: none;
  border-radius: 6px;
  background: none;
  cursor: pointer;
}

.hamburger-btn:hover,
.hamburger-btn[aria-expanded='true'] {
  background: rgba(255, 255, 255, 0.1);
}

.hamburger-icon {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 22px;
}

.hamburger-icon span {
  display: block;
  height: 2px;
  border-radius: 1px;
  background: var(--gold-light);
}

/* Dropdown floats over page content (not part of #app's own stacking),
   cream/white so it reads against any page it opens on top of, rather
   than staying navy like the header bar it hangs from. Right-aligned to
   the button so it never runs off the right edge of the viewport, and
   comfortably tap-sized throughout for the "primarily viewed on phones"
   requirement. */
.hamburger-dropdown {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 20;
  min-width: 220px;
  max-width: calc(100vw - 2rem);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(15, 31, 61, 0.18);
  padding: 0.4rem;
}

.hamburger-user-email {
  padding: 0.55rem 0.75rem 0.4rem;
  color: var(--muted);
  font-size: 0.78rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-bottom: 1px solid var(--border);
  margin-bottom: 0.3rem;
}

.hamburger-item {
  display: block;
  width: 100%;
  text-align: left;
  border: none;
  background: none;
  color: var(--navy);
  font-weight: 600;
  font-size: 0.92rem;
  padding: 0.6rem 0.75rem;
  border-radius: 6px;
  cursor: pointer;
}

.hamburger-item:hover {
  background: var(--bg);
}

/* Desktop nav bar -- a second strip beneath the main header row, showing
   all four feature links directly rather than behind the hamburger, once
   there's room for them. Hidden by default (mobile-first); the breakpoint
   below both reveals this and hides .site-nav-menu, so exactly one of the
   two navigation styles is ever visible or reachable at a given width. */
.site-nav-bar {
  display: none;
  background: var(--navy-light);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.site-nav-bar-inner {
  max-width: 900px;
  margin: 0 auto;
  padding: 0.6rem 1.5rem;
  display: flex;
  justify-content: center;
  gap: 2.25rem;
}

.site-nav-bar-link {
  border: none;
  background: none;
  color: #dfe3ec;
  font-weight: 600;
  font-size: 0.88rem;
  cursor: pointer;
  padding: 0.15rem 0;
  border-bottom: 2px solid transparent;
  text-decoration: none;
}

.site-nav-bar-link:hover {
  color: #fff;
  border-bottom-color: var(--gold-light);
}

@media (min-width: 720px) {
  .site-nav-bar {
    display: block;
  }
  .site-nav-menu {
    display: none;
  }
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

.logo-link {
  display: inline-block;
  line-height: 0;
  border-radius: 6px;
}

/* Explicit "Home" link next to the logo -- the logo image itself already
   navigates home (see initLogoHomeLink, js/app.js), but that's only
   discoverable if a visitor already knows to click a logo; this makes the
   same action visible as its own labeled control. Shares the click
   handler with the logo link (see wireBackHomeLinks, js/app.js). */
.back-home-link {
  display: inline-flex;
  align-items: center;
  color: var(--gold-light);
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.back-home-link:hover {
  color: #fff;
  text-decoration: underline;
}

@media (max-width: 560px) {
  .back-home-link {
    display: none;
  }
}

.logo-img {
  display: block;
  height: 48px;
  width: auto;
  max-width: 100%;
  border-radius: 4px;
}

@media (max-width: 480px) {
  .logo-img {
    height: 36px;
  }
}

main {
  max-width: 900px;
  margin: 0 auto;
  padding: 2rem 1.25rem 4rem;
}

.card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 2rem;
  box-shadow: 0 1px 3px rgba(15, 31, 61, 0.06);
}

h1,
h2,
h3 {
  font-family: var(--font-serif);
}

h1 {
  font-size: 1.8rem;
  margin: 0 0 0.75rem;
  color: var(--navy);
}

h2 {
  font-size: 1.3rem;
  margin: 2rem 0 0.5rem;
  color: var(--navy);
}

h3 {
  margin: 0 0 0.5rem;
  color: var(--navy);
  font-size: 1.05rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.lede {
  color: var(--muted);
  font-size: 1.02rem;
}

.eyebrow {
  font-family: var(--font-sans);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--muted);
  margin: 0 0 0.4rem;
}

/* Keyboard focus is visible on every interactive element, site-wide. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition-duration: 0.001ms !important;
    animation-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

.btn {
  display: inline-block;
  border: none;
  border-radius: 6px;
  padding: 0.7rem 1.4rem;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  transition: opacity 0.15s ease;
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--navy);
  color: #fff;
}

.btn-primary:hover:not(:disabled) {
  background: var(--navy-light);
}

.btn-secondary {
  background: #eee9dd;
  color: var(--navy);
  margin-right: 0.75rem;
}

.btn-danger {
  background: var(--danger-text);
  color: #fff;
}

.btn-danger:hover:not(:disabled) {
  opacity: 0.88;
}

.btn-secondary:hover:not(:disabled) {
  background: #e3ddca;
}

/* Size modifier for a call-to-action that needs to stand out beyond the
   normal .btn-primary/.btn-secondary weight -- currently just the Ticker
   Tester button on the results screen. Navy is this site's blue accent
   (there's no separate lighter "blue" token in the palette), so pairing
   this with .btn-primary is what makes it read as a prominent blue CTA. */
.btn-large {
  padding: 1rem 2rem;
  font-size: 1.1rem;
}

.error-text {
  color: var(--danger-text);
  margin-top: 1rem;
}

.error-text-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1rem;
}

.error-text-row .error-text {
  margin-top: 0;
}

/* Shared loading indicator (see spinnerHtml() in app.js) -- a small ring
   that inherits the surrounding text color via currentColor, so it matches
   whether it's sitting in navy body text, a muted note, or on a filled
   button. */
.spinner {
  display: inline-block;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  vertical-align: -0.2em;
  animation: spinner-rotate 0.7s linear infinite;
}

.spinner + span {
  margin-left: 0.5rem;
}

@keyframes spinner-rotate {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation-duration: 1.8s;
  }
}

/* Shared icon sizing — icons are inline SVG using currentColor, sized via
   font-size on whichever container places them (chip, heading, badge, etc). */
.category-icon svg,
.category-chip-icon svg,
.risk-icon svg,
.review-chevron svg,
.compass-motif svg {
  width: 1em;
  height: 1em;
  display: block;
}

.compass-motif {
  display: inline-flex;
  font-size: 1.1rem;
  color: var(--gold);
}

/* Landing */

/* Flex-wrap (not a fixed-column grid) so 7 items -- a count that never
   divides evenly into 2 or 3 columns -- resolve into a naturally centered
   last row instead of a grid leaving an orphaned single item stranded in
   column 1 with empty cells beside it. Centered, matching every other
   element in this card (see the centered eyebrow/h1/lede/CTA row under
   .intro-hero below) -- everything here is deliberately centered as one
   consistent block rather than mixing centered and left-aligned pieces. */
.category-preview-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.9rem;
  margin: 1.75rem 0;
}

.category-preview-item {
  display: flex;
  flex: 0 1 128px;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.5rem;
  padding: 0.9rem 0.5rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.category-preview-item .category-icon {
  font-size: 1.6rem;
  color: var(--navy);
  width: 2.4rem;
  height: 2.4rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  border-radius: 50%;
  border: 1px solid var(--border);
}

.category-preview-label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text);
}

.mini-stepper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  margin: 0.5rem 0 1.25rem;
}

.mini-stepper-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--gold-light);
}

.mini-stepper-text {
  color: var(--muted);
  font-size: 0.85rem;
  margin-left: 0.4rem;
}

/* Landing hero: the site's one deliberate navy "major section" beyond the
   header (see the palette note in :root) — light text on navy, gold CTA.
   More generous, responsive padding and a larger/tighter heading than the
   site's other .card sections get, specifically here, for a more
   confident "landing page" feel without changing any other screen. */
.intro-hero {
  background: var(--navy);
  border-color: var(--navy);
  padding: 3rem 3.25rem 2.75rem;
  text-align: center;
}

@media (max-width: 560px) {
  .intro-hero {
    padding: 2rem 1.5rem 1.75rem;
  }
}

.intro-hero h1 {
  color: #fff;
  font-size: clamp(1.9rem, 4vw, 2.6rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin-bottom: 1.1rem;
}

.intro-hero .lede {
  color: #cdd3de;
  max-width: 58ch;
  margin-left: auto;
  margin-right: auto;
}

.intro-hero .eyebrow {
  color: var(--gold-light);
}

.intro-hero .mini-stepper-text {
  color: #cdd3de;
}

/* CTA button and the "start over" link sit in one row so the link reads
   as a secondary, lower-emphasis option beside the primary action rather
   than stacked beneath it -- .btn-link-inline itself stays block-level
   everywhere else it's used (its own line), this only changes it here. */
.intro-cta-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  flex-wrap: wrap;
}

.intro-cta-row .btn-link-inline {
  display: inline;
  margin: 0;
}

.intro-privacy-note {
  color: #9aa3b5;
  font-size: 0.82rem;
  margin: 0.85rem 0 0;
}

.intro-hero .error-text {
  color: #ffb4a8;
}

.intro-hero .btn-primary {
  background: var(--gold);
  color: var(--navy);
}

.intro-hero .btn-primary:hover:not(:disabled) {
  background: var(--gold-light);
}

.btn-link-inline {
  display: block;
  margin: 0.75rem 0 0;
  border: none;
  background: none;
  color: #cdd3de;
  text-decoration: underline;
  font-size: 0.85rem;
  cursor: pointer;
  padding: 0;
}

.btn-link-inline:hover {
  color: #fff;
}

/* Survey */

.category-chips {
  display: flex;
  gap: 0.3rem;
  margin-bottom: 1.25rem;
  border-bottom: 2px solid var(--border);
  padding-bottom: 0.6rem;
}

.category-chip {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  border: none;
  background: none;
  color: var(--muted);
  padding: 0.2rem 0.2rem 0.6rem;
  font-size: 0.72rem;
  font-weight: 600;
  cursor: pointer;
  position: relative;
  transition: color 0.12s ease;
}

.category-chip::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.62rem;
  height: 2px;
  background: transparent;
}

.category-chip.visited {
  color: var(--navy);
}

.category-chip.visited::after {
  background: var(--gold-light);
}

.category-chip.active {
  color: var(--navy);
}

.category-chip.active::after {
  background: var(--navy);
}

.category-chip:disabled {
  cursor: not-allowed;
  opacity: 0.45;
}

.category-chip:not(:disabled):hover {
  color: var(--navy);
}

.category-chip-icon {
  font-size: 1.15rem;
}

.category-chip-label {
  text-align: center;
  line-height: 1.15;
}

@media (max-width: 620px) {
  .category-chip-label {
    display: none;
  }
}

.step-label {
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 600;
  margin: 0 0 0.25rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
}

/* Pins the current step's "Step X of Y" + category name to the top of the
   viewport while the client scrolls through that category's questions, so
   they're never left wondering which section they're answering without
   scrolling back up. Each survey step only ever shows one category at a
   time (see renderSurvey in app.js), so this never needs to swap between
   categories mid-scroll -- it just keeps the one already at the top of
   this step in view. Sits inside .survey-card's own padding rather than
   spanning edge-to-edge, so it reads as part of the page, not an overlay. */
.survey-sticky-header {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--card-bg);
  padding: 0.5rem 0 0.6rem;
  margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
}

.survey-sticky-header .step-label {
  margin: 0 0 0.2rem;
}

.survey-sticky-header h1 {
  margin: 0;
}

h1 .category-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  color: var(--gold);
  margin-right: 0.5rem;
  vertical-align: -0.15em;
}

.scale-hint {
  color: var(--muted);
  margin-bottom: 1.5rem;
}

.question-row {
  padding: 1rem 0.75rem;
  margin: 0 -0.75rem;
  border-top: 1px solid var(--border);
  border-radius: 6px;
  transition: background 0.15s ease;
}

.question-row:first-child {
  border-top: none;
}

.question-row.touched {
  background: var(--bg);
}

.question-text {
  margin: 0 0 0.6rem;
  font-weight: 500;
}

.scale {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.scale-btn {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 2px solid var(--border);
  background: #fff;
  color: var(--navy);
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.scale-btn:hover {
  border-color: var(--gold-light);
}

.scale-btn.selected {
  width: 48px;
  height: 48px;
  background: var(--navy);
  border-color: var(--navy);
  color: #fff;
  box-shadow: 0 2px 6px rgba(15, 31, 61, 0.25);
}

.scale-btn.selected svg {
  width: 22px;
  height: 22px;
}

/* Every question starts on 3 (neutral default) with this checkmark shown
   in gray, distinguishing "untouched default" from a real answer — even
   when the real answer turns out to be 3 too. The moment a question is
   interacted with at all, app.js adds .touched to its .question-row
   (tracked per-question via state.touchedQuestionIds, independent of
   which value was clicked), and this rule stops applying — the ordinary
   navy .scale-btn.selected styling above takes over from then on. Purely
   visual: state.answers[q.id] is set to the real value either way, so
   this has no effect on scoring. */
.question-row:not(.touched) .scale-btn.selected {
  background: var(--neutral-bg);
  border-color: var(--border);
  color: var(--neutral-text);
  box-shadow: none;
}

.scale-labels {
  display: flex;
  justify-content: space-between;
  max-width: 260px;
  color: var(--muted);
  font-size: 0.78rem;
  margin-top: 0.35rem;
}

.nav-row {
  margin-top: 2rem;
  display: flex;
  justify-content: flex-end;
}

.sub-input {
  margin-top: 0.85rem;
  max-width: 360px;
}

.sub-input label {
  display: block;
  font-size: 0.8rem;
  color: var(--muted);
  margin-bottom: 0.3rem;
}

.sub-input input,
.sub-input select {
  width: 100%;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.92rem;
  color: var(--text);
  background: #fff;
}

.sub-input input:focus,
.sub-input select:focus {
  outline: 2px solid var(--gold-light);
  outline-offset: 1px;
}

.horizon-options {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: 420px;
}

.horizon-option {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.92rem;
  color: var(--text);
  transition: all 0.12s ease;
}

.horizon-option:hover {
  border-color: var(--gold-light);
}

.horizon-option.selected {
  border-color: var(--navy);
  background: var(--bg);
  font-weight: 600;
  color: var(--navy);
}

.horizon-option input {
  accent-color: var(--navy);
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

/* Review */

.review-category {
  border-top: 1px solid var(--border);
}

.review-category:first-of-type {
  border-top: none;
}

.review-category-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 0;
}

.review-category-toggle {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  border: none;
  background: none;
  cursor: pointer;
  padding: 0;
  text-align: left;
  min-width: 0;
}

.review-chevron {
  color: var(--muted);
  font-size: 0.9rem;
  flex-shrink: 0;
  transition: transform 0.15s ease;
}

.review-category.expanded .review-chevron {
  transform: rotate(90deg);
  color: var(--navy);
}

.review-category-toggle .category-icon {
  font-size: 1.05rem;
  color: var(--navy);
  flex-shrink: 0;
}

.review-category-title {
  font-weight: 700;
  color: var(--navy);
  flex-shrink: 0;
}

.review-avg-meter {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  flex: 1;
}

.review-avg-track {
  flex: 1;
  max-width: 140px;
  height: 6px;
  border-radius: 3px;
  background: var(--border);
  overflow: hidden;
}

.review-avg-fill {
  display: block;
  height: 100%;
  background: var(--gold-light);
}

.review-avg-label {
  font-size: 0.78rem;
  color: var(--muted);
  white-space: nowrap;
}

.review-edit-btn {
  border: none;
  background: none;
  color: var(--gold-text);
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
  flex-shrink: 0;
}

.review-edit-btn:hover {
  text-decoration: underline;
}

.review-answer-list {
  list-style: none;
  margin: 0;
  padding: 0 0 1rem;
}

.review-answer-list li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.4rem 0;
  border-top: 1px solid var(--bg);
  font-size: 0.92rem;
}

.review-answer-list li:first-child {
  border-top: none;
}

.review-q-text {
  color: var(--text);
}

.review-q-answer {
  color: var(--navy);
  font-weight: 600;
  white-space: nowrap;
}

/* Results */

.summary-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin: 1.25rem 0 1.5rem;
}

@media (max-width: 620px) {
  .summary-grid {
    grid-template-columns: 1fr;
  }
}

.summary-box {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem 1.25rem;
}

/* Marked up as <h2> (not <h3>) so the heading level correctly follows the
   page's own <h1> without a gap -- these two boxes are the first heading
   after the page title, not nested three levels under it. Kept at the
   same visual size/layout as the rest of the site's h3s (small, flex-
   aligned for the optional icon) since heading LEVEL is a document-
   structure/accessibility concern, not a font-size one. */
.summary-box h2 {
  font-size: 1.05rem;
  margin: 0 0 0.5rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.priority-list {
  margin: 0;
  padding-left: 1.2rem;
}

.muted {
  color: var(--muted);
  font-size: 0.92rem;
}

.risk-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 700;
  font-size: 1.1rem;
  padding: 0.3rem 0.8rem;
  border-radius: 6px;
  margin: 0.1rem 0 0.5rem;
}

.risk-icon {
  font-size: 1rem;
  display: flex;
}

.sector-chart {
  margin: 1rem 0 1.5rem;
  padding: 1rem 1.25rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.values-profile-section {
  margin: 1.5rem 0;
}

.values-profile-chart-wrap {
  position: relative;
  max-width: 380px;
  margin: 0.75rem auto 0;
}

.financial-score-framing-note {
  margin: 0 0 1rem;
  padding: 0.7rem 1rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--muted);
  font-size: 0.82rem;
  font-style: italic;
}

.sector-chart h3 {
  margin-bottom: 0.75rem;
}

.sector-chart-layout {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.sector-donut-wrap {
  flex: 0 0 180px;
  width: 180px;
  height: 180px;
}

@media (max-width: 640px) {
  .sector-chart-layout {
    flex-direction: column;
  }

  .sector-donut-wrap {
    flex: none;
    margin: 0 auto;
  }
}

.sector-chart-rows {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.sector-chart-row {
  display: grid;
  grid-template-columns: 150px 1fr 24px;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.82rem;
}

@media (max-width: 480px) {
  .sector-chart-row {
    grid-template-columns: 1fr 24px;
    grid-template-areas: 'label label' 'track count';
    row-gap: 0.25rem;
  }

  .sector-chart-label {
    grid-area: label;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
  }

  .sector-chart-track {
    grid-area: track;
  }

  .sector-chart-count {
    grid-area: count;
  }
}

.sector-chart-label {
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sector-chart-track {
  height: 10px;
  border-radius: 5px;
  background: var(--border);
  overflow: hidden;
}

.sector-chart-fill {
  display: block;
  height: 100%;
  background: var(--navy);
  border-radius: 5px;
}

.sector-chart-count {
  color: var(--muted);
  font-weight: 600;
  text-align: right;
}

.risk-conservative {
  background: var(--success-bg);
  color: var(--success-text);
}

.risk-balanced {
  background: var(--warn-bg);
  color: var(--warn-text);
}

.risk-growth {
  background: #e7edfb;
  color: #1c4a9c;
}

.table-wrap {
  overflow-x: auto;
  margin-top: 0.5rem;
}

.results-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
  min-width: 640px;
}

.results-table th,
.results-table td {
  text-align: left;
  padding: 0.5rem 0.7rem;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

.results-table th {
  background: var(--bg);
  color: var(--navy);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Zebra striping + hover -- scoped to .holdings-table only (not the
   simulation breakdown table, which shares .results-table's base styling
   but uses its own row backgrounds for excluded/total rows that a
   td-level zebra background would otherwise paint over), and only above
   the 700px breakpoint where the table is still a real table -- below it
   each td becomes its own full-width block (see the mobile card layout
   further down), where a td-level background would band the card instead
   of tinting a table row. */
@media (min-width: 701px) {
  .holdings-table tbody tr:nth-child(even) td {
    background: var(--bg);
  }

  .holdings-table tbody tr:hover td {
    background: #efe9da;
  }
}

.holding-remove-btn {
  border: none;
  background: none;
  color: var(--muted);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.15rem 0.4rem;
  border-radius: 4px;
}

.holding-remove-btn:hover {
  color: var(--danger-text);
  background: var(--danger-bg);
}

.holding-remove-confirm-row td {
  background: var(--danger-bg);
  border: 1px solid #eecfcd;
  border-radius: 8px;
  padding: 0.85rem 1rem;
}

.portfolio-repopulate-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: -0.25rem 0 1rem;
}

.portfolio-repopulate-row .muted {
  margin: 0;
}

.results-table tbody tr.row-strong td:first-child {
  border-left: 3px solid var(--success-text);
}

.results-table tbody tr.row-partial td:first-child {
  border-left: 3px solid var(--warn-text);
}

.results-table tbody tr.row-below-threshold td:first-child {
  border-left: 3px solid var(--neutral-text);
}

/* Below this width, the table reflows into a stack of cards — one per
   holding — instead of forcing horizontal scroll. Ticker + Company act as
   the card header, Sector/Match Tier as labeled metadata rows (label
   supplied by the td's data-label attribute), Rationale as body text. */
@media (max-width: 700px) {
  .table-wrap {
    overflow-x: visible;
  }

  .results-table {
    min-width: 0;
  }

  .results-table thead {
    display: none;
  }

  .results-table,
  .results-table tbody,
  .results-table tr,
  .results-table td {
    display: block;
    width: 100%;
  }

  .results-table tr {
    margin-bottom: 1rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.85rem 1rem;
    background: #fff;
  }

  .results-table tr.row-strong {
    border-left: 4px solid var(--success-text);
  }

  .results-table tr.row-partial {
    border-left: 4px solid var(--warn-text);
  }

  .results-table tr.row-below-threshold {
    border-left: 4px solid var(--neutral-text);
  }

  .results-table tbody tr.row-strong td:first-child,
  .results-table tbody tr.row-partial td:first-child,
  .results-table tbody tr.row-below-threshold td:first-child {
    border-left: none;
  }

  .results-table td {
    border-bottom: none;
    padding: 0.3rem 0;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
  }

  .results-table td::before {
    content: attr(data-label);
    font-weight: 700;
    color: var(--navy);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    flex-shrink: 0;
  }

  .results-table td[data-label='Ticker'] {
    justify-content: flex-start;
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--navy);
    padding-bottom: 0;
  }

  .results-table td[data-label='Company'] {
    justify-content: flex-start;
    color: var(--muted);
    font-size: 0.85rem;
    padding-top: 0;
    padding-bottom: 0.6rem;
    margin-bottom: 0.35rem;
    border-bottom: 1px solid var(--bg);
  }

  .results-table td[data-label='Ticker']::before,
  .results-table td[data-label='Company']::before {
    content: none;
  }

  .results-table td[data-label='Rationale'] {
    display: block;
  }

  .results-table td[data-label='Rationale']::before {
    display: block;
    margin-bottom: 0.3rem;
  }

  .results-table td[data-label='Remove'] {
    justify-content: flex-end;
    padding-top: 0.4rem;
  }

  .results-table td[data-label='Remove']::before {
    content: none;
  }

  .holding-remove-confirm-row td {
    display: block;
    padding: 0.85rem 1rem;
  }
}

.tier-badge {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
}

.tier-strong {
  background: var(--success-bg);
  color: var(--success-text);
}

.tier-partial {
  background: var(--warn-bg);
  color: var(--warn-text);
}

.tier-below-threshold {
  background: var(--neutral-bg);
  color: var(--neutral-text);
}

/* Ticker Tester's own relabeling of the same "Below Values Threshold" tier
   as "Low Match" in red -- see tickerTierDisplay() in ticker-tester.js.
   The main portfolio results table keeps .tier-below-threshold above,
   unchanged. */
.tier-low-match {
  background: var(--danger-bg);
  color: var(--danger-text);
}

.financial-score-badge {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
}

.financial-score-above {
  background: var(--score-above-bg);
  color: var(--score-above-text);
}

.financial-score-average {
  background: var(--score-average-bg);
  color: var(--score-average-text);
}

.financial-score-below {
  background: var(--score-below-bg);
  color: var(--score-below-text);
}

.partial-note {
  color: var(--warn-text);
  font-size: 0.82rem;
  font-style: italic;
  margin-top: 0.25rem;
}

/* Deliberately a bordered badge, not italic inline text like .partial-note,
   so a financial concern reads as visually distinct from a values-fit
   trade-off at a glance (they can both appear on the same holding). */
.caution-note {
  color: var(--danger-text);
  background: var(--danger-bg);
  border: 1px solid #eecfcd;
  border-radius: 6px;
  padding: 0.4rem 0.6rem;
  font-size: 0.8rem;
  font-weight: 600;
  margin-top: 0.4rem;
}

.financial-toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-top: 0.5rem;
  border: none;
  background: none;
  color: var(--gold-text);
  font-weight: 600;
  font-size: 0.8rem;
  cursor: pointer;
  padding: 0;
}

.financial-toggle-btn:hover {
  text-decoration: underline;
}

.financial-toggle-chevron {
  font-size: 0.75rem;
  display: flex;
  transition: transform 0.15s ease;
}

.financial-toggle-chevron.open {
  transform: rotate(90deg);
}

/* Wraps the rationale paragraph + optional partial-match note + the
   financial-metrics list once "Why this holding" is expanded -- keeping
   all of a row's supporting detail under one toggle instead of the two
   separate always-visible/toggle blocks this used to be split across. */
.holding-details {
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
}

.holding-rationale-text {
  margin: 0 0 0.5rem;
  color: var(--text);
}

.financial-details-list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0.6rem 0.75rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.82rem;
  color: var(--text);
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.rationale p {
  margin: 0 0 0.85rem;
}

.simulation-section {
  margin-top: 1.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}

.simulation-hero {
  font-family: var(--font-serif);
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.3;
  margin: 0.5rem 0 0.4rem;
}

.simulation-hero.positive {
  color: var(--success-text);
}

.simulation-hero.negative {
  color: var(--danger-text);
}

.simulation-coverage-note {
  color: var(--muted);
  font-size: 0.85rem;
  margin: 0 0 0.75rem;
}

.simulation-toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  border: 1px solid var(--border);
  background: var(--card-bg);
  color: var(--navy);
  font-weight: 600;
  font-size: 0.85rem;
  padding: 0.5rem 0.85rem;
  border-radius: 6px;
  cursor: pointer;
}

.simulation-toggle-btn:hover {
  border-color: var(--gold);
  color: var(--gold-text);
}

.simulation-table-wrap {
  margin-top: 1rem;
}

.simulation-row-excluded {
  background: var(--neutral-bg);
}

.simulation-excluded-note {
  color: var(--neutral-text);
  font-size: 0.85rem;
  font-style: italic;
}

.simulation-pct-positive {
  color: var(--success-text);
  font-weight: 600;
}

.simulation-pct-negative {
  color: var(--danger-text);
  font-weight: 600;
}

.simulation-total-row td {
  font-weight: 700;
  border-top: 2px solid var(--border);
  border-bottom: none;
  color: var(--navy);
}

.section-divider {
  display: flex;
  justify-content: center;
  color: var(--gold-light);
  margin: 2rem 0 0.5rem;
}

.section-divider svg {
  width: 1.5rem;
  height: 1.5rem;
}

#restart-btn {
  margin-top: 1.75rem;
}

/* Account: login/sign-up screen and "Save My Portfolio". All optional — see
   auth.js — so these only ever render when Firebase is actually
   available. */

.auth-card {
  max-width: 420px;
  margin: 0 auto;
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin-top: 1.25rem;
}

.auth-form label {
  font-size: 0.82rem;
  color: var(--muted);
  margin: 0.6rem 0 0.3rem;
}

.auth-form input {
  width: 100%;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.95rem;
  color: var(--text);
  background: #fff;
}

.auth-form input:focus {
  outline: 2px solid var(--gold-light);
  outline-offset: 1px;
}

.auth-submit-btn {
  margin-top: 1rem;
  width: 100%;
}

/* Password field with an inline Show/Hide toggle -- used for both the
   password and retype-password inputs on the login/signup screen. */
.password-field-wrap {
  position: relative;
}

.password-field-wrap input {
  padding-right: 3.6rem;
}

.password-toggle-btn {
  position: absolute;
  top: 50%;
  right: 0.6rem;
  transform: translateY(-50%);
  border: none;
  background: none;
  color: var(--gold-text);
  font-weight: 600;
  font-size: 0.82rem;
  cursor: pointer;
  padding: 0.2rem 0.3rem;
}

.password-toggle-btn:hover {
  color: var(--navy);
}

/* Sign-up-only "I have read the Terms of Service" checkbox row -- required
   before account creation (see the submit handler in renderAccount(),
   js/auth.js). The Terms of Service words themselves open the modal below
   without submitting the form or losing whatever's already been typed. */
.terms-checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 0.9rem 0 0;
  font-size: 0.85rem;
  color: var(--text);
  cursor: pointer;
}

.terms-checkbox-row input[type='checkbox'] {
  margin-top: 0.2rem;
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  cursor: pointer;
}

.terms-link-btn {
  display: inline;
  border: none;
  background: none;
  color: var(--gold-text);
  font-weight: 600;
  cursor: pointer;
  padding: 0;
  font: inherit;
  text-decoration: underline;
}

.terms-link-btn:hover {
  color: var(--navy);
}

/* Generic modal overlay -- currently only the Terms of Service dialog uses
   it, but kept name-generic since nothing here is Terms-specific. Appended
   directly to <body> by JS (see openTermsModal, js/auth.js), never rendered
   through #app, so opening/closing it never disturbs whatever screen is
   underneath. */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 31, 61, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  z-index: 100;
}

.modal-card {
  background: #fff;
  border-radius: 10px;
  max-width: 640px;
  width: 100%;
  max-height: 85vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 12px 40px rgba(15, 31, 61, 0.3);
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.1rem 1.5rem;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}

.modal-header h2 {
  margin: 0;
  font-size: 1.15rem;
}

.modal-close-btn {
  border: none;
  background: none;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
  padding: 0.25rem 0.5rem;
}

.modal-close-btn:hover {
  color: var(--navy);
}

.modal-body {
  padding: 1.1rem 1.5rem 1.5rem;
  overflow-y: auto;
}

.modal-body h3 {
  margin: 1.25rem 0 0.4rem;
  font-size: 1rem;
}

.modal-body h3:first-child {
  margin-top: 0;
}

.modal-body p {
  margin: 0 0 0.75rem;
  color: var(--text);
  font-size: 0.9rem;
  line-height: 1.55;
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.75rem;
  margin-top: 1rem;
}

.csv-preview-text {
  margin: 0;
  padding: 0.9rem 1rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--text);
  overflow-x: auto;
  white-space: pre;
}

.modal-actions .btn-secondary {
  margin-right: 0;
}

.auth-info-text {
  color: var(--success-text);
  font-size: 0.85rem;
  margin: 0.75rem 0 0;
}

.auth-link {
  color: var(--gold-text);
  font-size: 0.85rem;
}

.auth-link:hover {
  color: var(--navy);
}

.auth-card .auth-link {
  display: block;
  margin-top: 1rem;
}

.auth-switch {
  font-size: 0.88rem;
  color: var(--muted);
  margin: 1.5rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.auth-switch-btn {
  border: none;
  background: none;
  color: var(--gold-text);
  font-weight: 600;
  font-size: 0.88rem;
  cursor: pointer;
  padding: 0;
  margin-left: 0.3rem;
}

.auth-switch-btn:hover {
  text-decoration: underline;
}

/* "Save My Portfolio" (Results screen) — a single button whose own label
   carries most states; the 5-portfolio-limit case gets its own small block
   with a link into My Portfolios instead. */

.results-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin: 1.25rem 0 1.75rem;
}

.results-toolbar-item {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

/* Forces the "5 portfolios saved" limit notice and the finished share-link
   row onto their own full-width line below any buttons already in the
   toolbar, rather than squeezing in as an oddly-wide flex item beside them. */
.results-toolbar-full {
  flex-basis: 100%;
}

.save-results-error {
  margin-left: 0.75rem;
}

.save-results-limit {
  margin: 0.75rem 0 1.25rem;
  padding: 0.85rem 1rem;
  background: var(--danger-bg);
  border: 1px solid #eecfcd;
  border-radius: 8px;
}

.save-results-limit p {
  margin: 0 0 0.5rem;
}

.save-results-link {
  border: none;
  background: none;
  color: var(--gold-text);
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  padding: 0;
}

.save-results-link:hover {
  text-decoration: underline;
}

.share-results-row {
  margin: 0.75rem 0 1.25rem;
}

.share-results-error {
  margin-left: 0.75rem;
}

.share-results-done {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.share-results-link-input {
  flex: 1;
  min-width: 12rem;
  max-width: 26rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.5rem 0.7rem;
  font-size: 0.85rem;
  color: var(--muted);
  background: var(--surface);
}

/* Shared-result recipient screen (?shared=<id>) */

.shared-result-card {
  max-width: 720px;
  margin: 0 auto;
}

.shared-result-holdings {
  list-style: none;
  margin: 1rem 0 1.75rem;
  padding: 0;
}

.shared-result-holding {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0;
  border-top: 1px solid var(--border);
  font-size: 0.9rem;
}

.shared-result-holding:first-child {
  border-top: none;
}

.shared-result-ticker {
  font-weight: 700;
  color: var(--navy);
  min-width: 3.2rem;
}

.shared-result-name {
  color: var(--text);
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.shared-result-sector {
  color: var(--muted);
  font-size: 0.8rem;
  white-space: nowrap;
}

/* My Portfolios list */

.portfolios-card {
  max-width: 640px;
  margin: 0 auto;
}

.portfolios-list {
  list-style: none;
  margin: 1.25rem 0 0;
  padding: 0;
}

.portfolio-entry {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 0;
  border-top: 1px solid var(--border);
}

.portfolio-entry:first-child {
  border-top: none;
}

.portfolio-entry-info {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.portfolio-entry-name {
  font-weight: 600;
  color: var(--navy);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.portfolio-entry-date {
  font-size: 0.8rem;
  color: var(--muted);
}

.portfolio-entry-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-shrink: 0;
}

.btn-link-action {
  border: none;
  background: none;
  color: var(--gold-text);
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
  padding: 0.2rem 0;
}

.btn-link-action:hover {
  text-decoration: underline;
}

.btn-link-action:disabled {
  color: var(--muted);
  cursor: not-allowed;
  text-decoration: none;
}

.btn-link-action.danger {
  color: var(--danger-text);
}

.portfolio-entry-renaming {
  display: block;
}

.portfolio-rename-form {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
}

.portfolio-rename-input {
  flex: 1;
  min-width: 0;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.92rem;
  color: var(--text);
  background: #fff;
}

.portfolio-rename-input:focus {
  outline: 2px solid var(--gold-light);
  outline-offset: 1px;
}

.portfolio-entry-confirming {
  display: block;
  padding: 0.85rem 1rem;
  background: var(--danger-bg);
  border: 1px solid #eecfcd;
  border-radius: 8px;
  margin: 0.4rem 0;
}

.portfolio-delete-confirm-text {
  margin: 0 0 0.6rem;
  color: var(--text);
}

.portfolio-delete-confirm-actions {
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

/* Ticker Tester */

.ticker-tester-card {
  max-width: 720px;
  margin: 0 auto;
}

.ticker-search {
  position: relative;
  margin: 1.25rem 0;
}

.ticker-search label {
  display: block;
  font-size: 0.82rem;
  color: var(--muted);
  margin: 0 0 0.3rem;
}

.ticker-search input {
  width: 100%;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.95rem;
  color: var(--text);
  background: #fff;
}

.ticker-search input:focus {
  outline: 2px solid var(--gold-light);
  outline-offset: 1px;
}

.ticker-search-results {
  position: absolute;
  z-index: 10;
  top: 100%;
  left: 0;
  right: 0;
  margin: 0.3rem 0 0;
  padding: 0.3rem 0;
  list-style: none;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 4px 14px rgba(15, 31, 61, 0.12);
  max-height: 320px;
  overflow-y: auto;
}

.ticker-search-result {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  width: 100%;
  padding: 0.55rem 0.9rem;
  border: none;
  background: none;
  text-align: left;
  cursor: pointer;
  font-size: 0.9rem;
}

.ticker-search-result:hover {
  background: var(--bg);
}

.ticker-search-result-ticker {
  font-weight: 700;
  color: var(--navy);
  min-width: 3.2rem;
}

.ticker-search-result-name {
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}

.ticker-search-result-sector {
  color: var(--muted);
  font-size: 0.78rem;
  white-space: nowrap;
}

.ticker-search-empty {
  padding: 0.7rem 0.9rem;
  color: var(--muted);
  font-size: 0.88rem;
}

.ticker-result {
  margin-top: 1.5rem;
}

.ticker-result-change-row {
  margin: 0 0 1rem;
}

.ticker-result-summary h2 {
  margin: 0 0 0.5rem;
}

.ticker-result-rationale {
  margin: 0.6rem 0 0.2rem;
}

.ticker-result-note {
  margin: 0.3rem 0 0;
}

.ticker-personalize-prompt {
  padding: 0.85rem 1rem;
  background: var(--warn-bg);
  border: 1px solid #f0e0bb;
  border-radius: 8px;
  margin-bottom: 1.25rem;
}

.ticker-personalize-prompt p {
  margin: 0 0 0.75rem;
  color: var(--text);
}

.ticker-personalize-actions {
  margin: 0 !important;
}

.ticker-categories {
  margin-top: 1.75rem;
}

.ticker-category-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1.5rem;
  align-items: center;
  margin-top: 1rem;
}

@media (max-width: 640px) {
  .ticker-category-layout {
    grid-template-columns: 1fr;
  }
}

.ticker-radar-wrap {
  position: relative;
  max-width: 380px;
  margin: 0 auto;
}

.ticker-radar-unavailable {
  text-align: center;
  margin-top: 0.5rem;
}

.ticker-category-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.ticker-category-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(60px, 100px) 44px;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0;
  border-top: 1px solid var(--border);
  font-size: 0.86rem;
}

.ticker-category-row:first-child {
  border-top: none;
}

.ticker-category-label {
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ticker-category-track {
  height: 8px;
  border-radius: 4px;
  background: var(--border);
  overflow: hidden;
}

.ticker-category-fill {
  display: block;
  height: 100%;
  background: var(--gold);
  border-radius: 4px;
}

/* 1-3 red, 4-6 yellow, 7-10 green -- same danger/warn/success tokens used
   for tier badges and risk badges elsewhere, so a "bad" category score
   reads the same as everywhere else on the site. */
.ticker-category-fill-low {
  background: var(--danger-text);
}

.ticker-category-fill-mid {
  background: var(--warn-text);
}

.ticker-category-fill-high {
  background: var(--success-text);
}

.ticker-category-score {
  color: var(--navy);
  font-weight: 700;
  text-align: right;
  white-space: nowrap;
}

.ticker-category-score-low {
  color: var(--danger-text);
}

.ticker-category-score-mid {
  color: var(--warn-text);
}

.ticker-category-score-high {
  color: var(--success-text);
}

.ticker-raw-data {
  margin-top: 0.5rem;
}

.ticker-raw-data h3 {
  margin-bottom: 0.75rem;
}

.ticker-raw-data-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.ticker-raw-data-list li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.55rem 0;
  border-top: 1px solid var(--border);
  font-size: 0.9rem;
}

.ticker-raw-data-list li:first-child {
  border-top: none;
}

.ticker-raw-data-list li span:first-child {
  color: var(--muted);
}

.ticker-raw-data-list li span:last-child {
  color: var(--text);
  font-weight: 600;
  text-align: right;
}

/* Compare Two Companies */

.ticker-compare-cta-row {
  margin: 0 0 1.5rem;
}

.ticker-compare-login-prompt {
  margin-bottom: 1.5rem;
}

.ticker-compare-card {
  max-width: 960px;
  margin: 0 auto;
}

.ticker-compare-pickers {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1.5rem;
  margin: 1.25rem 0;
}

@media (max-width: 640px) {
  .ticker-compare-pickers {
    grid-template-columns: 1fr;
  }
}

.ticker-compare-slot {
  position: relative;
}

.ticker-compare-slot-label {
  display: block;
  font-size: 0.82rem;
  color: var(--muted);
  margin: 0 0 0.3rem;
}

.ticker-compare-slot label {
  display: block;
  font-size: 0.82rem;
  color: var(--muted);
  margin: 0 0 0.3rem;
}

.ticker-compare-slot input {
  width: 100%;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.95rem;
  color: var(--text);
  background: #fff;
}

.ticker-compare-slot input:focus {
  outline: 2px solid var(--gold-light);
  outline-offset: 1px;
}

.ticker-compare-selected {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
}

.ticker-compare-selected-name {
  font-weight: 600;
  color: var(--navy);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ticker-compare-results {
  margin-top: 1.5rem;
}

.ticker-compare-columns {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 2rem;
}

@media (max-width: 640px) {
  .ticker-compare-columns {
    grid-template-columns: 1fr;
  }
}

.ticker-compare-column h2 {
  margin: 0 0 0.5rem;
  font-size: 1.1rem;
}

.ticker-compare-category-list {
  margin-top: 1rem;
}

.ticker-compare-chart-section {
  margin-top: 2rem;
  text-align: center;
}

.ticker-compare-radar-wrap {
  max-width: 460px;
}

.ticker-compare-verdict {
  margin-top: 1.75rem;
  padding: 1rem 1.25rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-left: 4px solid var(--gold);
  border-radius: 8px;
}

.ticker-compare-verdict p {
  margin: 0;
  color: var(--text);
}

/* Watchlist */

/* Reuses .ticker-search's own layout/input styling wholesale (see Ticker
   Tester above) -- this rule just adds the bottom margin that search box
   didn't need in its original context, to separate it from the entry
   list below. */
.watchlist-add-picker {
  margin-bottom: 1.5rem;
}

.watchlist-toggle-wrap {
  display: inline-flex;
  align-items: baseline;
  gap: 0.6rem;
  margin: 0.4rem 0;
}

.watchlist-toggle-btn {
  white-space: nowrap;
}

.watchlist-toggle-btn-active {
  color: var(--navy);
}

.watchlist-card {
  max-width: 720px;
  margin: 0 auto;
}

.watchlist-list {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
}

.watchlist-entry {
  border-top: 1px solid var(--border);
  padding: 0.4rem 0;
}

.watchlist-entry:first-child {
  border-top: none;
}

.watchlist-entry-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  border: none;
  background: none;
  padding: 0.4rem 0;
  cursor: pointer;
  text-align: left;
  font-size: 0.92rem;
}

.watchlist-entry-ticker {
  font-weight: 700;
  color: var(--navy);
  min-width: 3.2rem;
}

.watchlist-entry-name {
  color: var(--text);
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.watchlist-entry-sector {
  color: var(--muted);
  font-size: 0.8rem;
  white-space: nowrap;
}

.watchlist-entry-detail {
  padding: 0 0 0.75rem 1.9rem;
}

/* Learn: hub, per-lesson reading/quiz/result, login-gated same as My
   Portfolios/My Watchlist above -- see js/learn.js. */

.learn-hub-card,
.learn-lesson-card {
  max-width: 640px;
  margin: 0 auto;
}

/* Gift-box progress bar -- the bar is the primary visual, the text tracker
   underneath (.learn-progress-label) is a supporting caption, not its own
   separate element. The gift box sits at the bar's own end rather than as
   a fixed page element, so it visually reads as "what you're filling the
   bar toward." See giftBoxIcon (js/badges.js) for the three lid states. */
.learn-progress-wrap {
  margin: 1.1rem 0 0.25rem;
}

.learn-progress-bar-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.learn-progress-track {
  flex: 1;
  height: 8px;
  border-radius: 999px;
  background: var(--neutral-bg);
  overflow: hidden;
}

.learn-progress-fill {
  height: 100%;
  background: var(--gold);
  border-radius: 999px;
  transition: width 0.3s ease;
}

.learn-progress-giftbox {
  flex-shrink: 0;
  line-height: 0;
}

.gift-box-icon {
  width: 34px;
  height: 34px;
  overflow: visible;
}

.gift-box-body {
  fill: var(--gold);
  stroke: var(--navy);
  stroke-width: 1.3;
}

.gift-box-ribbon-v {
  fill: var(--navy);
  opacity: 0.85;
}

.gift-box-lid {
  fill: var(--gold-light);
  stroke: var(--navy);
  stroke-width: 1.3;
}

.gift-box-bow {
  fill: var(--navy);
  opacity: 0.85;
}

.gift-lid {
  transform-origin: 20px 16px;
  transform: rotate(0deg) translate(0, 0);
}

.gift-lid-open {
  transform: rotate(-22deg) translate(-3px, -4px);
}

.gift-lid-opening {
  animation: gift-lid-open-keyframes 0.7s ease forwards;
}

@keyframes gift-lid-open-keyframes {
  0% {
    transform: rotate(0deg) translate(0, 0);
  }
  45% {
    transform: rotate(-30deg) translate(-5px, -7px);
  }
  100% {
    transform: rotate(-22deg) translate(-3px, -4px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .gift-lid-opening {
    animation: none;
    transform: rotate(-22deg) translate(-3px, -4px);
  }
}

.learn-progress-label {
  margin: 0.4rem 0 0;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--muted);
}

.learn-lesson-list {
  list-style: none;
  margin: 1.25rem 0 0;
  padding: 0;
}

.learn-lesson-item {
  border-top: 1px solid var(--border);
}

.learn-lesson-item:first-child {
  border-top: none;
}

/* The actual clickable row -- a real <button> (not a <li role="button">,
   which is invalid ARIA: a role of "button" isn't allowed on a list item,
   and it stops the <li> counting as a real list item to the accessibility
   tree, breaking the enclosing <ul>'s own list semantics too). */
.learn-lesson-item-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  padding: 0.9rem 0;
  border: none;
  background: none;
  font: inherit;
  text-align: left;
  color: inherit;
  cursor: pointer;
}

.learn-lesson-item-btn:hover .learn-lesson-item-title {
  text-decoration: underline;
}

.learn-lesson-item-btn:focus-visible {
  outline: 2px solid var(--gold-light);
  outline-offset: 2px;
}

.learn-lesson-item-info {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}

.learn-lesson-item-title {
  font-weight: 600;
  color: var(--navy);
}

.learn-lesson-item-desc {
  font-size: 0.82rem;
  color: var(--muted);
}

.learn-lesson-body p {
  margin: 0 0 1rem;
  line-height: 1.65;
}

.learn-lesson-body p:last-child {
  margin-bottom: 0;
}

.quiz-question {
  border: none;
  padding: 0;
  margin: 0 0 1.5rem;
}

.quiz-question legend {
  padding: 0;
  font-weight: 600;
  color: var(--navy);
  margin-bottom: 0.6rem;
}

.quiz-options {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.quiz-option {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.92rem;
}

.quiz-option:hover {
  border-color: var(--gold-light);
}

.quiz-option input {
  margin-top: 0.2rem;
  flex-shrink: 0;
}

.learn-quiz-result {
  text-align: center;
  margin: 1.5rem 0;
}

.learn-quiz-score {
  font-family: var(--font-serif);
  font-size: 2.5rem;
  font-weight: 700;
  color: var(--navy);
  margin: 0 0 0.35rem;
}

/* Badges: header slot, My Badges list, and the one-time earned-badge
   pop-up -- see js/badges.js. */

.badge-medallion-icon {
  display: block;
  width: 100%;
  height: 100%;
}

/* Header slot (inside #account-widget, see renderAccountWidget/auth.js) --
   only ever rendered when a badge is actually equipped (renderEquippedBadgeHtml
   returns '' otherwise), so there's never an empty placeholder to style
   around. */
.header-badge {
  display: inline-flex;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
}

.badge-earned-card {
  max-width: 380px;
  text-align: center;
  padding: 2rem 1.75rem 1.75rem;
}

.badge-earned-visual {
  width: 96px;
  height: 96px;
  margin: 0 auto 1rem;
}

.badge-earned-card h2 {
  margin: 0 0 0.6rem;
}

.badge-earned-text {
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.55;
  margin: 0;
}

.badge-earned-actions {
  justify-content: center;
  margin-top: 1.5rem;
}

.my-badges-card {
  max-width: 560px;
  margin: 0 auto;
}

.badge-list {
  list-style: none;
  margin: 1.25rem 0 0;
  padding: 0;
}

.badge-list-item {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.9rem 0;
  border-top: 1px solid var(--border);
}

.badge-list-item:first-child {
  border-top: none;
}

.badge-list-visual {
  width: 48px;
  height: 48px;
  flex-shrink: 0;
}

.badge-list-visual-locked {
  filter: grayscale(1);
  opacity: 0.45;
}

.badge-list-info {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
  flex: 1;
}

.badge-list-name {
  font-weight: 600;
  color: var(--navy);
}

.badge-list-desc {
  font-size: 0.82rem;
}

.site-footer {
  text-align: center;
  color: var(--muted);
  font-size: 0.8rem;
  padding: 1.5rem;
}

.footer-brand {
  font-family: var(--font-serif);
  font-weight: 700;
  color: var(--navy);
}

/* Single consolidated disclaimer, always present in the footer on every
   screen. The summary line intentionally uses --text (not --muted) so it
   reads clearly rather than disappearing as low-contrast fine print; the
   full text underneath is the union of every disclaimer/data-limitation
   note previously scattered across the results page. */
.site-disclaimer {
  max-width: 640px;
  margin: 0 auto;
}

.site-disclaimer-summary {
  margin: 0;
  color: var(--text);
  font-size: 0.85rem;
}

.site-disclaimer-toggle {
  border: none;
  background: none;
  color: var(--gold-text);
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
  padding: 0;
  margin-left: 0.35rem;
  text-decoration: underline;
}

.site-disclaimer-toggle:hover {
  color: var(--navy);
}

.site-footer-links {
  margin: 0.6rem 0 0;
}

.site-footer-links .site-disclaimer-toggle:first-child {
  margin-left: 0;
}

.site-disclaimer-full {
  margin-top: 0.85rem;
  background: var(--danger-bg);
  color: var(--danger-text);
  border: 1px solid #eecfcd;
  border-radius: 8px;
  padding: 1rem 1.25rem;
  font-size: 0.82rem;
  text-align: left;
}

.site-disclaimer-full p {
  margin: 0 0 0.75rem;
}

.site-disclaimer-full p:last-child {
  margin-bottom: 0;
}

/* Print -- strips chrome (nav, buttons, footer disclaimer toggle) so a
   printed/saved-as-PDF results page reads as a clean takeaway document
   rather than a screenshot of the web app. */
@media print {
  .site-header,
  .site-footer,
  .skip-link,
  .results-toolbar,
  .modal-overlay,
  .global-error-banner,
  .offline-banner,
  button {
    display: none !important;
  }

  body {
    background: #fff;
  }

  .card {
    box-shadow: none;
    border: none;
    padding: 0;
  }
}
