/* Roboto (latin), self-hosted variable font — replaces the Google Fonts @import
   so no visitor IP reaches fonts.googleapis.com / fonts.gstatic.com (GC-268).
   The variable woff2 covers the whole 100-900 axis; app uses 400/500/600/800. */
@font-face {
    font-family: "Roboto";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("/assets/fonts/roboto/roboto-latin.woff2") format("woff2");
}

:root {
    /* GC-305/GC-267: three-surface model. Mirror of colors.py surface_* —
       keep in sync. Page↔card contrast ~1.20 (was ~1.10). */
    --surface-chrom: #111117;
    --surface-page: #17171f;    /* page background */
    --surface-card: #1f1f2b;    /* card + chart surface */
    --surface-raised: #282834;   /* L* 16.6  (+4.3 from card) */
    --surface-hover:  #31313D;   /* L* 20.8  (+4.2 from raised) only use on zebra */
    --surface-header: #1A1A24;   /* L* ~10.2 (~-2 from card) — grid header/footer band, between page and card */

    /* GC-305: the one gutter between cards — grid gap, stacked-card gap, and
       row gutter all reference this so pages stay consistent. Keep it wider
       than the 0.75rem card padding and narrower than the 2rem outer margin. */
    --gc-gutter: 1.6rem;

    /* Public section (public_content.py): shared content boundary that the
       header, footer, landing and card-less pages align their edge to, and the
       base body font size. See the "Public section" block below. */
    --gc-public-max: 1100px;
    --gc-public-font: 16px;

    --primary-color: #003f5c;
    --secondary-color: #fd9d51;
    --tertiary-color: #9ecbed;   /* GC-263: collapsed #9dcbed onto colors.py PALE_BLUE (one-digit drift) */
    --text-color: #dadada;
    --inactive-text-color: #86868b;
    --background-color: var(--surface-page);
    --hover-text-color: #222222;
    --corner-radius: 0;
    --bs-primary: #50748f;
    --bs-primary-rgb: 80, 116, 143;
    --bs-link-color: #50748f;
    --bs-link-hover-color: #003f5c;
    /* Defensive pin. The vendored Bootswatch cyborg (5.3.6) redefines --bs-body-bg
       (#060606) on :root; if it loads after this file it wins the specificity tie
       and turns the page background black. Root cause is fixed in app_factory
       (assets_path_ignore keeps vendor/ out of auto-loaded assets so cyborg loads
       before this file); !important keeps us safe if that ordering ever regresses. */
    --bs-body-bg: var(--surface-page) !important;
    --bs-body-bg-rgb: 23, 23, 31 !important;
    /* --bs-body-color: #e0e0e0; */ /* left inactive as before (was dead code behind a dangling comment) */
    --bs-body-font-family: "Roboto", system-ui, -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    --gc-chart-bg: white;
}

/* Drop font size improves feel of site */
html { 
    font-size: 14px; 
}

/* Drop card padding */
.card-body {
    padding: 0.75rem !important;  /* 12px */
}

/* GC-305: drop card borders. Cards read as a raised surface, never a border —
   "a border OR a raised surface, never both, never nested." No card sets an
   inline border, so this global rule removes Bootstrap's default .card hairline
   everywhere (framed_card and raw dbc.Card alike). */
.card {
    border: none !important;
}

/* GC-305: card headers are part of the one flat card surface — drop Bootstrap's
   default border-bottom hairline (a border) and cap tint. */
.card-header {
    border-bottom: none !important;
    background-color: transparent !important;
}

/* GC-347: chart headings as HTML rather than a Plotly title, inside the same
   card as the chart (components.cards.chart_card).

   Left-aligned on purpose. A Plotly title is centred over the plot area, which
   gives it no shared edge with the controls above it or the prose beside it, so
   a column of charts reads as a stack of posters. Aligning to the card's own
   text edge puts every heading on one vertical line down the page.

   The subtitle is not decoration - it carries the population and the scale
   caveat, and on the stage grids the caveat is what stops the accepted grid
   being read as comparable with the availability grid. Muted, but present. */
.gc-chart-title {
    color: var(--text-color);
    /* 20px: between the published article scale's h3 (18px) and h2 (22px).
       18 read small against a 560px grid, 22 reads as leading a section rather
       than labelling a chart. Set explicitly rather than left to Bootstrap's
       h3, which is 1.75rem / 24.5px and shouts over the chart it names. */
    font-size: 20px;
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: -.01em;
    margin: 0;
    text-align: left;
}

.gc-chart-subtitle {
    color: var(--inactive-text-color);
    /* 16px, a step ABOVE the 14px root. Deliberately not small print: this
       line carries the scale caveat, which a reader has to actually take in for
       the chart above it to be read correctly. Colour does the subordinating
       (muted against the title's full-strength text), size does not. */
    font-size: 16px;
    font-weight: 400;
    line-height: 1.4;
    margin: 0;
    text-align: left;
}

/* Space below the heading block, not between its two lines: title and subtitle
   are one unit and should sit tight to each other. `:last-child` so a card with
   a title and no subtitle still gets the gap. */
.gc-chart-title { margin-bottom: 2px; }
.gc-chart-title:last-child,
.gc-chart-subtitle {
    margin-bottom: 12px;
}

/* Square corners, and a little more room above the heading than beside it.

   The corners are the point. `--corner-radius: 0` is this design system's
   stated token (line 40) but it was never wired to `--bs-card-border-radius`
   (see the commented-out attempt further down), so dbc.Card keeps Bootstrap's
   default ~6px radius. On a chart card that does not matter while the card
   contrasts with the page - but here the card background and the Plotly
   figure's `paper_bgcolor` are the SAME token, so the rounded top corners are
   the only thing marking where the card starts, and they read as a stray line
   across the top of the chart. Squared, the card and the figure fuse into one
   surface, which is what a chart card is supposed to be.

   Scoped to `.gc-chart-card`, not `.card`, deliberately: squaring every card
   app-wide is a GC-305 decision, not a side effect of one page's design pass.

   The padding has to be a rule rather than an inline style because the global
   `.card-body { padding: 0.75rem !important }` beats anything a call site sets. */
.gc-chart-card {
    border-radius: 0 !important;
    /* GC-347: IBM Plex Sans on the chart card only, to match the figure's own
       typeface (chart_builders.stage_zone_maps.CHART_FONT). Resolved from the
       local system, NOT from Google Fonts - GC-268 self-hosted Roboto precisely
       so no visitor IP reaches fonts.googleapis.com. Falls through to Roboto
       where Plex is not installed. Self-host a woff2 next to roboto-latin when
       this goes site-wide. */
    font-family: "IBM Plex Sans", Roboto, system-ui, -apple-system,
        "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}

.gc-chart-card > .card-body {
    padding-top: 16px !important;
    padding-bottom: 0 !important;
}

/* Row-of-card-columns: one gutter horizontally AND vertically so a stack of
   card rows has equal gaps in both directions. `--bs-gutter-x` spaces the
   columns; `margin-bottom` spaces this row from the next (replaces `mb-3`,
   which was 1rem — a different value, and !important, so it must be dropped
   from the className). Only gutter-x, not -y (gutter-y's negative top-margin
   would pull the row up into anything above it). */
.gc-row-gutter {
    --bs-gutter-x: var(--gc-gutter);
    margin-bottom: var(--gc-gutter);
}

/* GC-305: shared chart-grid rule. Cards have no borders, so the gutter is the
   only separator — keep it wider than the 0.75rem card padding. `gap` sets the
   row gap == column gap. Columns auto-fit to a min width, overridable per page
   via `--gc-chart-min`. Replaces the per-page inline `d-grid` + gap + template. */
.gc-chart-grid {
    display: grid;
    /* Columns fill by default (--gc-chart-max: 1fr); set --gc-chart-max to a
       fixed width to cap card width instead (e.g. the interconnectors groups). */
    grid-template-columns: repeat(auto-fit, minmax(var(--gc-chart-min, 380px), var(--gc-chart-max, 1fr)));
    gap: var(--gc-gutter);         /* gutter = row gap = col gap, > card padding */
    margin-top: var(--gc-gutter);  /* separate the grid from the controls above it */
}

/* GC-305: map (MapLibre/Mapbox) attribution pill — match the card surface and
   chart text instead of the default white pill with blue links. */
.maplibregl-ctrl-attrib,
.maplibregl-ctrl-attrib.maplibregl-compact,
.mapboxgl-ctrl-attrib,
.mapboxgl-ctrl-attrib.mapboxgl-compact {
    background-color: var(--surface-card) !important;
}
.maplibregl-ctrl-attrib,
.maplibregl-ctrl-attrib a,
.mapboxgl-ctrl-attrib,
.mapboxgl-ctrl-attrib a {
    color: var(--text-color) !important;  /* == colors.chart_text */
}
/* The ⓘ toggle: MapLibre bakes a near-black icon SVG — replace it with a
   chart_text (#dadada) one and match the surface, for both open and closed. */
.maplibregl-ctrl-attrib-button,
.mapboxgl-ctrl-attrib-button {
    background-color: var(--surface-card) !important;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23dadada' d='M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z'/%3E%3C/svg%3E") !important;
}


/* Base / inactive navbar link */
.ec-nav-link {
  color: var(--inactive-text-color, #aaa);
  border: 1px solid transparent;         /* optional subtle underline or border */
  border-radius: 0.25rem;                /* optional for focus ring */
  text-decoration: none;                 /* remove underline */
  transition: color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
  line-height: 1.2;
  /* padding-top: 0.5rem;  */
  /* padding-bottom: 0.5rem; */
}

/* Base (inactive) */
a.ec-nav-link {
  color: var(--inactive-text-color);
  background-color: transparent;
  border-radius: var(--corner-radius);
  text-decoration: none;
  transition: color .15s ease, filter .15s ease, background-color .15s ease;
  font-weight: 400;
}

/* Hover – DIM (to match button feel) */
a.ec-nav-link:hover {
  color: var(--hover-text-color);
  background-color: transparent;
  text-decoration: none;
  font-weight: 400;
}

/* Active (current page) – persistent “selected” state */
a.ec-nav-link.active,
.navbar-nav .nav-link.active {
  color: var(--text-color);
  background-color: transparent;
  font-weight: 600;
  filter: none;                       /* don’t dim when active */
}

/* Keyboard focus (accessibility) */
a.ec-nav-link:focus-visible {
  outline: 2px solid var(--text-color);
  outline-offset: 2px;
}


/* a.ec-nav-link { */
/*     background-color: transparent !important; */
/*     border-radius: var(--corner-radius) !important; */
/*     color: var(--inactive-text-color) !important; */
/* } */
/**/
/* a.ec-nav-link.active { */
/*     background-color: transparent;  */
/*     color: var(--text-color) !important; */
/*     font-weight: 600; */
/* } */

/* a.ec-nav-link:hover { */
/*     background-color: transparent;  */
/*     color: var(--text-color) !important; */
/*     font-weight: 600; */
/* } */
/**/

/* Base (inactive) */
.btn-outline-light {
  --bs-btn-bg: transparent;
  color: var(--inactive-text-color);
  border-color: var(--inactive-text-color);
}

/* Hover */
.btn-outline-light:hover {
  color: var(--text-color);
  border-color: var(--text-color);
  background-color: transparent;
  filter: brightness(1.0); /* increase if you want brightness at instance of hover */
}

/* Active / checked (covers both toggle + manual .active) */
.btn-check:checked + .btn-outline-light,
.btn-check:active + .btn-outline-light,
.btn-outline-light.active,
.btn-outline-light:active {
  color: var(--text-color);
  border-color: var(--text-color);
  background-color: transparent;
}

.form-select.bg-dark.text-light {
  background-color: #111117 !important;
  color: var(--text-color) !important;
  border: 1px solid #555 !important;
  border-color: var(--text-color) !important;
  transition: background-color 0.2s ease, border-color 0.2s ease;
  /* filter: invert(1) brightness(1.2); */
}

/* in assets/custom.css */
.form-select.bg-dark.text-light {
  background-color: #111117 !important;
  color: var(--text-color) !important;
  border: 1px solid #555 !important;
  border-color: var(--text-color) !important;
  transition: background-color 0.2s ease, border-color 0.2s ease;

  /* Replace the default chevron */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ffffff'%3E%3Cpath d='M3.204 5.793a1 1 0 0 1 1.414 0L8 9.172l3.382-3.379a1 1 0 0 1 1.415 1.414l-4.09 4.086a1 1 0 0 1-1.414 0L3.204 7.207a1 1 0 0 1 0-1.414z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.8em center;
  background-size: 0.9em auto;
  padding-right: 2em; /* leave room for the icon */
  appearance: none;   /* hide default arrow */
}

/* Bootstrap Collapse transition override - CHANGE HERE to adjust collapse animation speed */
.collapse {
    transition: height 350ms ease;  /* Default is ~350ms, adjust as needed */
}

.collapsing {
    transition: height 350ms ease;  /* Default is ~350ms, adjust as needed */
}

/* Collapsible section header - clickable */
.ec-nav-section-toggle {
    font-size: 1.0rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    color: var(--inactive-text-color, #aaa);
    margin-top: 0.75rem;
    padding-left: 1rem;
    cursor: pointer;
    transition: opacity 0.15s ease;
    user-select: none;  /* Prevent text selection on click */
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.ec-nav-section-toggle:hover {
    opacity: 0.9;
}

/* Chevron icon in section header */
.ec-nav-section-toggle .bi {
    font-size: 0.875rem;
    transition: transform 0.15s ease;
    min-width: 1rem;  /* Prevent layout shift */
}

/* Keep chevron visible and subtle */
.ec-nav-section-toggle .bi.bi-chevron-right {
    opacity: 0.6;
}

.ec-nav-section-toggle .bi.bi-chevron-down {
    opacity: 0.6;
}

/* GC-305: mobile nav drawer (#mobile-sidebar) rides the chrome surface, set
   inline in make_navbar. Default offcanvas header carries a light border and a
   dark (black) close icon — invisible on the dark surface. Whiten the close
   icon, make the title light, and mute the header divider to match the chrome. */
#mobile-sidebar .offcanvas-title {
    color: var(--text-color);
}
#mobile-sidebar .offcanvas-header {
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
#mobile-sidebar .btn-close {
    /* Bootstrap's .btn-close-white treatment: invert the dark SVG to white. */
    filter: invert(1) grayscale(100%) brightness(200%);
}

/* GC-319: public auth pages (login, get-access, request-trial, auth/magic)
   render without app-shell chrome. <html> gets gc-hide-sidebar before first
   paint (the pre-paint script in app_factory's index_string) and it's kept in
   sync across SPA nav by a clientside callback. Hide the desktop sidebar column
   and the mobile hamburger, and let the content column run full width. */
html.gc-hide-sidebar #sidebar-col,
html.gc-hide-sidebar #open-sidebar {
    display: none !important;
}
html.gc-hide-sidebar #page-container {
    /* Override the Bootstrap col-lg-9/col-xl-10 width with the sidebar gone. */
    flex: 0 0 100% !important;
    width: 100% !important;
    max-width: 100% !important;
}
/* With the sidebar gone the content column is full-bleed, so the public-content
   twins (About/Glossary/Explainers) — which the static Flask pages centre via
   body.gc-public-page — would otherwise jam to the left gutter. Re-centre their
   .gc-public-page wrapper to the same --gc-public-max the static pages use, so
   the in-shell twin matches its crawlable static twin. Auth pages centre their
   own cards (no .gc-public-page) and static pages never carry gc-hide-sidebar,
   so both are untouched. */
html.gc-hide-sidebar #page-container .gc-public-page {
    max-width: var(--gc-public-max);
    margin-inline: auto;
}

/* Page summary collapsible toggle */
.page-summary-toggle {
    font-size: 1.0rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    opacity: 0.7;
    margin-bottom: 0.5rem;
    cursor: pointer;
    transition: opacity 0.15s ease;
    user-select: none;  /* Prevent text selection on click */
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.page-summary-toggle:hover {
    opacity: 0.9;
}

/* Chevron icon in page summary toggle */
.page-summary-chevron {
    font-size: 0.875rem;
    transition: transform 0.15s ease;
    min-width: 1rem;  /* Prevent layout shift */
    opacity: 0.6;
    display: inline-block;
}

/* AG Grid dark theme overrides */
.ag-theme-alpine-dark {
    --ag-background-color: var(--surface-card);
    /* Header + footer sit on --surface-header (a half-step below the card) so the
       title row and pagination read as a distinct band, not flush with the data. */
    --ag-header-background-color: var(--surface-header);
    --ag-odd-row-background-color: var(--surface-raised);  /* zebra stripe */
    --ag-row-hover-color: var(--surface-hover);
    --ag-foreground-color: #dadada;
    --ag-header-foreground-color: #dadada;
    --ag-border-color: #2a2a2a;
    --ag-font-family: "Roboto", system-ui, -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    --ag-font-size: 13px;
    --ag-header-font-size: 13px;
    --ag-header-font-weight: 600;
}

/* GC-305: differentiate the grid's title row and pagination footer. 2px rule
   beneath the header (and above the footer) to bound the band; footer shares
   the --surface-header band. Global — applies to every AG grid. */
.ag-theme-alpine-dark .ag-header {
    border-bottom: 2px solid var(--surface-hover);
}
.ag-theme-alpine-dark .ag-paging-panel {
    background-color: var(--surface-header);
    border-top: 2px solid var(--surface-hover);
}

/* Drop the resize-handle line trailing the last column — there's nothing beyond
   it to resize against, so it reads as a stray pipe after the final header. */
.ag-theme-alpine-dark .ag-header-cell.ag-column-last .ag-header-cell-resize::after {
    display: none;
}

/* Markdown tables (used in explainer pages and page summaries) */
.gc-markdown table {
    border-collapse: collapse;
    margin: 1rem 0;
}

.gc-markdown th,
.gc-markdown td {
    border: 1px solid #2a2a2a;
    padding: 0.4rem 0.8rem;
    text-align: left;
}

.gc-markdown th {
    font-weight: 600;
    background-color: var(--surface-page);
}

.gc-markdown td {
    background-color: var(--surface-card);
}

/* Summary stats tables (dbc.Table.gc-summary-table). Align them with the AG
   grids on the same/adjacent pages: horizontal row rules only (drop the vertical
   cell borders from bordered=True), AG-matched row height, header band on
   --surface-header, and the AG border colour. */
.gc-summary-table {
    --bs-table-border-color: #2a2a2a;  /* == --ag-border-color */
    /* Thin edge around the table, like the AG grid's --ag-root-wrapper border,
       in --surface-raised. */
    border: 1px solid var(--surface-raised) !important;
}
/* Row rules only (drop the left/right verticals from bordered=True), and AG-
   matched row height via padding. Padding is set directly with !important —
   .table-sm ties on specificity, so the --bs-table-cell-padding-* vars alone
   lose. In px (root font is 14px here): ~11.8px y → 42px rows to match
   --ag-row-height; 15px x matches AG's cell padding. */
.gc-summary-table td,
.gc-summary-table th {
    border-left: 0 !important;
    border-right: 0 !important;
    padding: 11.8px 15px !important;
    font-size: 13px !important;  /* == --ag-font-size; overrides the inline 0.85rem (~12px) */
}

/* Header band on --surface-header, matching the AG grid header. 2px surface-
   hover rule beneath the header row (matches the AG header rule; collapses over
   the 1px cell border). */
.gc-summary-table thead th {
    background-color: var(--surface-header) !important;
    --bs-table-accent-bg: var(--surface-header) !important;
    --bs-table-bg: var(--surface-header) !important;
    --bs-table-striped-bg: var(--surface-header) !important;
    border-bottom: 2px solid var(--surface-hover) !important;
}
.gc-summary-table thead tr {
    --bs-table-accent-bg: var(--surface-header) !important;
}

/* Body zebra matches the AG grid exactly: base rows = --surface-card, alternate
   = --surface-raised, hover = --surface-hover. AG's first data row is card, so
   stripe the 2nd/4th (nth-of-type even). Kill Bootstrap's translucent ±5% accent
   overlay (the box-shadow) so the solid tokens paint through. */
.gc-summary-table tbody tr > * {
    background-color: var(--surface-card) !important;
    box-shadow: none !important;
}
.gc-summary-table tbody tr:nth-of-type(even) > * {
    background-color: var(--surface-raised) !important;
}
.gc-summary-table tbody tr:hover > * {
    background-color: var(--surface-hover) !important;
}

/* Description prose measure. Started (GC-305) as a hand-maintained allowlist of
   the full-width pages, whose descriptions would otherwise run the whole screen
   width; every new full-width page had to remember to join it, and
   neso-monthly-stacks never did. Now applied to every description instead: on a
   narrow page the container is already inside 80ch, so the cap simply does
   nothing there and the allowlist bought nothing.
   680px, not the old 80ch, to match the published article measure exactly (see
   `.gc-flat .gc-markdown` below) now that descriptions carry the same 17px prose.
   `ch` was doing something subtly wrong here: it resolves against the font-size
   of the element it sits on, so on the 14px wrapper it capped 17px text at 629px,
   and moving it to the prose element overshot to 764px. A fixed measure is the
   honest way to say "the same column width as the articles". Set on the inner
   .gc-markdown so it constrains the prose, not the collapsible block. */
.gc-page-summary .gc-markdown {
    max-width: 680px;
}

/* Descriptions open with `##### Page Name`, so h5 is the page-summary TITLE
   convention rather than a deep sub-heading, and it has to sit above the 17px
   body rather than continue the h2→h4 ramp downward. h5 is unused in published
   prose (no explainer or report .md has one), so this is scoped to the
   description component and leaves the article pages free to define their own
   if one is ever wanted. First element in the block, hence no top margin. */
.gc-page-summary .gc-markdown h5 {
    font-weight: 600;
    font-size: 20px;
    margin: 0 0 .6rem;
    color: #f0f0f2;
}

/* Styled links using primary color */
/* GC-263: no-underline is the app-wide default (colour carries the link
   affordance), matching the public pages. Covers plain anchors and Bootstrap's
   link-styled buttons (.btn-link), which Reboot would otherwise underline. */
a,
.btn-link {
    text-decoration: none;
}

.gc-link {
    color: #50748f;
    transition: color 0.15s ease;
}

.gc-link:hover {
    color: #003f5c;
}

/* Override link colors in markdown content and cards. No underline (GC-263 Layer
   2: the app follows the public no-underline stance; colour carries the link
   affordance) — these are the only app content links that would otherwise inherit
   Bootstrap Reboot's default underline. */
.card a, .gc-markdown a {
    color: #50748f;
    text-decoration: none;
    transition: color 0.15s ease;
}

.card a:hover, .gc-markdown a:hover {
    color: #003f5c;
}

/* Override Bootstrap primary button colors (Cyborg theme uses hardcoded classes) */
.btn-primary {
    background-color: #003f5c !important;
    border-color: #003f5c !important;
    color: #ffffff !important;
}

.btn-primary:hover, .btn-primary:focus, .btn-primary:active {
    background-color: #50748f !important;
    border-color: #50748f !important;
}

/* Override Bootstrap warning button (used for logout) */
.btn-warning {
    background-color: #ee7201 !important;
    border-color: #ee7201 !important;
    color: #000000 !important;
}

.btn-warning:hover, .btn-warning:focus, .btn-warning:active {
    background-color: #cb6101 !important;
    border-color: #cb6101 !important;
}

.alert-warning {
    background-color: #ee7101 !important;
    border-color: #ee7101 !important;
    color: #000000 !important;
}

.alert-success {
    background-color: #50723C !important;
    border-color: #50723C !important;
    color: #ffffff !important;
}

/* CTA button hover animation (matches user avatar toggle) */
.gc-cta-btn {
    transition: transform 0.15s ease;
}

.gc-cta-btn:hover {
    transform: scale(1.04);
}

/* Full-width CTAs (e.g. the login magic-link button) are much wider, so the
   1.04 scale moves them far more in absolute px. Use a gentler factor so the
   hover growth reads similar to the content-width buttons (Get Access, Logout). */
.gc-cta-btn.w-100:hover {
    transform: scale(1.01);
}

/* Trial button: filled green, lightens on hover */
/* White CTA: mirrors the landing .gc-lp-cta — white fill, near-black text.
   Pair with .gc-cta-btn for the scale-on-hover. */
.gc-cta-white {
    background-color: #ffffff !important;
    color: #121212 !important;
    border: 1px solid var(--text-color) !important;
    border-radius: 0 !important;
    font-size: var(--gc-public-font) !important;
    transition: filter 0.15s ease, transform 0.15s ease;
}
.gc-cta-white:hover, .gc-cta-white:focus, .gc-cta-white:active {
    background-color: #ffffff !important;
    color: #111117 !important;
    filter: brightness(0.92);
}

/* Get Access form: inputs + textareas sit on the raised card surface
   (surface-card) against the flat surface-page form container. */
/* Get Access + Login + Logout page text sits at the public 16px scale (in-app base is 14px). */
#req-form,
#login-page,
#logout-page {
    font-size: var(--gc-public-font);
}

/* The password-reveal toggle reads as body text, not a small link
   (id beats Bootstrap's .btn-sm font-size). */
#login-password-toggle {
    font-size: var(--gc-public-font);
}

/* Auth-page links + link-buttons use the public hyperlink blue
   (--tertiary-color), scoped so app-wide .gc-link is untouched. */
#login-page a,
#login-page .btn-link,
#req-form a,
#req-form .btn-link {
    color: var(--tertiary-color) !important;
}
#login-page a:hover,
#login-page .btn-link:hover,
#req-form a:hover,
#req-form .btn-link:hover {
    color: var(--tertiary-color) !important;
    filter: brightness(0.9);
}

/* Password "Sign in" button: public hyperlink-blue text + border, squared
   corners; fills blue on hover. */
#login-submit {
    color: var(--tertiary-color) !important;
    border-color: var(--tertiary-color) !important;
    border-radius: 0 !important;
}
#login-submit:hover,
#login-submit:focus,
#login-submit:active {
    background-color: var(--tertiary-color) !important;
    border-color: var(--tertiary-color) !important;
    color: var(--surface-page) !important;
}

.gc-access-form .form-control {
    background-color: var(--surface-card) !important;
    color: var(--text-color) !important;
    border-color: var(--surface-raised) !important;
    font-size: var(--gc-public-font) !important;
}
.gc-access-form .form-control:focus {
    background-color: var(--surface-card) !important;
    color: var(--text-color) !important;
    border-color: var(--tertiary-color) !important;
}

/* Chrome paints autofilled inputs yellow and ignores `background-color`.
 * The -webkit-box-shadow inset trick is the standard workaround. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
    -webkit-box-shadow: 0 0 0 1000px #ffffff inset !important;
    -webkit-text-fill-color: #000000 !important;
    caret-color: #000000;
}

/* Footer — shared by the app (.gc-app-footer) and the public site
   (.gc-public-footer): a full-bleed surface-chrome band with links + copyright,
   so the two surfaces read consistently. Grouped selectors carry everything the
   two share; the thin context modifiers below carry only the genuine deltas.
   flex-shrink keeps the footer pinned by the sticky-footer flex column. */
.gc-app-footer, .gc-public-footer {
    background: var(--surface-chrom);
    flex-shrink: 0;
}
.gc-app-footer-inner, .gc-public-footer-inner {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem 1.25rem;
    align-items: center;
    justify-content: space-between;
}
.gc-app-footer-links, .gc-public-footer-links {
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
}
.gc-app-footer a, .gc-public-footer a {
    color: #c9c9cf;              /* orphan grey — token deferred to Layer 3 */
    text-decoration: none;
}
.gc-app-footer a:hover, .gc-public-footer a:hover {
    /* Converged on the public no-underline stance. App was #dadada + underline;
       #dadada == --text-color, so only the underline is removed. Weight bump on
       hover gives prominence in place of the dropped underline. */
    color: var(--text-color);
    font-weight: 600;
    text-decoration: none;
}
.gc-app-footer-copy, .gc-public-footer-copy {
    color: var(--inactive-text-color);   /* app was literal #86868b (same value) */
    font-size: 0.875rem;
}

/* Footer context modifiers — only the genuine deltas between the two surfaces. */
/* App: butts directly against the data row so the sidebar chrome meets the
   footer with no page-bg gap; spans full-bleed to match the navbar/sidebar. */
.gc-app-footer-inner { padding: 1.25rem 2rem; }
/* Public: breathes after prose, and aligns its content to the shared edge. */
.gc-public-footer { margin-top: 3rem; }
.gc-public-footer-inner {
    max-width: var(--gc-public-max);
    margin: 0 auto;
    padding: 1.25rem 1rem;
}

/* Shared nav-link idiom (GC-263 Layer 2) — the top app navbar (.gc-nav-link, a
 * dbc.Button) and the public site header nav (.gc-public-nav a) render
 * identically: plain text links, muted grey brightening to --text-color on hover,
 * no underline. Grouped here as one source of truth. The public selector is
 * qualified with .gc-public-header so it out-specifies the broader
 * `.gc-public-header a` colour rule regardless of source order. The inline
 * style="color" the app buttons used to fight was removed from app_factory, so no
 * !important is needed. Items sit ~1.25rem apart via the navbar flex gap. */
.gc-nav-link.btn,
.gc-public-header .gc-public-nav a {
    color: #c9c9cf;              /* orphan grey — token deferred to Layer 3 */
    text-decoration: none;
}
.gc-nav-link.btn:hover,
.gc-nav-link.btn:focus,
.gc-public-header .gc-public-nav a:hover {
    color: var(--text-color);
    font-weight: 600;
    text-decoration: none;
}
/* App-only: strip the dbc.Button chrome so it reads as a plain text link, matching
 * the public header's <a>. .btn lifts specificity above Bootstrap's .btn rules. */
.gc-nav-link.btn {
    padding: 0.35rem 0;
    border: 0;
    font-weight: 400;
    box-shadow: none;
}
.gc-nav-link.btn:hover,
.gc-nav-link.btn:focus {
    box-shadow: none;
}

/* ------------------------------------------------------------------------
 * Public section (server-rendered pages built in public_content.py:
 * _page_shell + the landing page). Relocated from an inline <style> block
 * (GC-263, Aug 2026) so the app and public site share one stylesheet.
 *
 * Colours here are being tokenised against :root incrementally. Exact-match
 * hex have been aliased to vars; the remaining literals (#c9c9cf, #d7d7d9,
 * #f0f0f2, #9a9aa6, #e6e6e8, rgba(255,255,255,...)) are orphan greys with no
 * token yet -- reconcile against the ramp in the Layer 2/3 consistency pass.
 * ------------------------------------------------------------------------ */

/* --- shared shell: header, footer, prose card, directories --- */
/* Shared content boundary for the public section (header, footer, landing
   and card-less pages all align their left/right edge to this). */
/* Sticky footer: body fills the viewport and the main grows, so the footer
   pins to the bottom on short pages instead of floating mid-page. Scoped to
   .gc-public-page (set on every public <body>) so these globals don't reflow
   the Dash app, which shares this stylesheet. */
body.gc-public-page { min-height: 100vh; display: flex; flex-direction: column; }
body.gc-public-page > main { flex: 1 0 auto; }
.gc-public-header, .gc-public-footer { flex-shrink: 0; }
/* Header + footer are full-bleed chrome bands (surface-chrome, matching the
   app navbar). The header spans the full width like the app navbar — brand
   hard-left, nav hard-right, with a small edge gutter — rather than being
   centred to --gc-public-max like the page bodies. No divider lines: the
   colour band separates them from the page. */
.gc-public-header {
  display: flex; align-items: baseline; gap: 1.5rem;
  padding: 1.1rem 1.25rem;
  background: var(--surface-chrom, #111117);
}
/* Brand wordmark: brighter than the nav links (#f0f0f2 vs #c9c9cf). Qualified
   with .gc-public-header to out-specify the `.gc-public-header a` colour rule
   that would otherwise dim it to the nav-link grey. */
.gc-public-header .gc-public-brand { font-weight: 700; font-size: 1.25rem; color: #f0f0f2; text-decoration: none; }
.gc-public-nav { display: flex; gap: 1.25rem; margin-left: auto; }
/* No underlines on any public-page link (nav, prose, footer, directory).
   Scoped to .gc-public-page so the app's link styling is untouched. */
.gc-public-page a { text-decoration: none; }
.gc-public-header a { color: #c9c9cf; }
.gc-public-header a:hover { color: var(--text-color); }
/* Mobile: the desktop header is a single flex row (brand + 5 nav links pushed
   hard-right with margin-left:auto). Below 640px that row is wider than the
   viewport, so the last link ("Sign In") clips off the right edge. Drop the
   auto margin, give the nav full width so its links wrap left-aligned under the
   brand, and tighten the gaps/padding. */
@media (max-width: 640px) {
  .gc-public-header { flex-wrap: wrap; gap: 0.5rem 1rem; padding: 0.9rem 1rem; }
  .gc-public-nav { margin-left: 0; width: 100%; flex-wrap: wrap; gap: 0.5rem 1rem; }
}
/* Public footer links are styled with the app footer (shared .gc-*-footer a rule). */
.gc-public {
  max-width: 640px; margin: 2rem auto; padding: 2rem 2.25rem 2.5rem;
  background: var(--surface-card, #1f1f2b); border: 1px solid rgba(255,255,255,.06);
  border-radius: 0;
}
/* Card-less prose pages: text sits directly on the page (surface-page). */
.gc-flat .gc-public {
  /* width:100% is load-bearing: body is a flex column, and `margin: auto`
     on a flex child would otherwise shrink it to its content (the 680px
     markdown), so pin the wrapper to the full --gc-public-max boundary; the
     markdown then centres *within* that boundary (see .gc-flat .gc-markdown). */
  width: 100%; max-width: var(--gc-public-max); margin: 2rem auto;
  padding: 0 1rem 2rem; background: transparent; border: 0;
}
/* Centre the narrow prose column within the 1100px boundary. Explainers (a wide
   directory, .gc-dir-main) fills that boundary, so left-aligning prose to its
   edge left a lopsided right-hand gap on the narrow prose pages; centring keeps
   the reading column balanced instead. */
.gc-flat .gc-markdown { max-width: 680px; margin-inline: auto; }
/* Explainers directory: full-width clickable rows with hairline dividers
   (it's a directory, not prose, so it spans the full --gc-public-max width). */
.gc-dir-main { max-width: var(--gc-public-max); margin: 2rem auto;
  padding: 0 1rem 3rem; color: var(--text-color, #dadada); font-size: 17px; }
.gc-dir-main h1 { font-weight: 600; font-size: 30px; letter-spacing: -.01em;
  margin: 0 0 1rem; color: var(--text-color); }
.gc-dir-intro { max-width: 680px; color: #d7d7d9; line-height: 1.7;
  margin: 0 0 1.75rem; }
.gc-dir { border-bottom: 1px solid rgba(255,255,255,.12); }
.gc-dir-row { display: grid; gap: 0.35rem 1.5rem; align-items: baseline;
  grid-template-columns: minmax(160px, 200px) 1fr auto;
  padding: 1.1rem 0; border-top: 1px solid rgba(255,255,255,.12);
  text-decoration: none; color: inherit; transition: background .12s ease; }
.gc-dir-row:hover { background: rgba(255,255,255,.04); }
.gc-dir-title { font-weight: 600; font-size: 20px; color: var(--text-color); }
.gc-dir-desc { color: #c9c9cf; line-height: 1.55; max-width: 80ch; }
.gc-dir-arrow { color: var(--inactive-text-color); font-size: 20px; align-self: center; }
.gc-dir-row:hover .gc-dir-arrow { color: var(--text-color); }
.gc-dir-foot { margin: 1.5rem 0 0; color: #c9c9cf; }
.gc-dir-foot a { color: var(--tertiary-color); }
@media (max-width: 640px) {
  .gc-dir-row { grid-template-columns: 1fr auto; }
  .gc-dir-desc { grid-column: 1 / -1; }
}
/* "What GenCharts offers" directory: same row pattern as .gc-dir — name +
   description left, feature list middle, access tier right, hairlines. */
.gc-offer { border-bottom: 1px solid rgba(255,255,255,.12); margin: 1.25rem 0 1.75rem; }
.gc-offer-row { display: grid; gap: 0.35rem 1.5rem; align-items: start;
  grid-template-columns: minmax(150px, 190px) 1fr auto;
  padding: 1.25rem 0; border-top: 1px solid rgba(255,255,255,.12); }
.gc-offer-name { font-weight: 600; font-size: 18px; color: var(--text-color); }
.gc-offer-desc { color: #9a9aa6; font-size: 14px; line-height: 1.5; margin-top: .3rem; }
.gc-offer-features { margin: 0; padding-left: 1.1rem; color: #c9c9cf;
  font-size: 15px; line-height: 1.6; }
.gc-offer-features li { margin: .15rem 0; }
.gc-offer-access { justify-self: end; align-self: start; white-space: nowrap;
  display: flex; flex-direction: column; align-items: flex-end; gap: .3rem; }
.gc-offer-tier { font-size: 12px; letter-spacing: .04em; text-transform: uppercase;
  color: #9a9aa6; }
.gc-offer-note { border-top: 1px solid rgba(255,255,255,.12); padding: 1.1rem 0;
  color: #c9c9cf; font-size: 15px; }
.gc-offer-note a { color: var(--tertiary-color); font-weight: 500; }
@media (max-width: 640px) {
  .gc-offer-row { grid-template-columns: 1fr; }
  .gc-offer-access { justify-self: start; align-items: flex-start; }
}
/* .gc-markdown is shared: public prose pages AND in-app markdown
   (components/explainer_card.py). These prose rules are scoped to
   .gc-public-page so they style the public pages only and leave the app's
   markdown (which keeps the .gc-markdown table/link rules earlier in this file)
   exactly as it was before GC-263. */
.gc-public-page .gc-markdown { font-size: 17px; line-height: 1.7; color: #d7d7d9; }
.gc-public-page .gc-markdown h1 {
  font-weight: 600; font-size: 30px; line-height: 1.25;
  letter-spacing: -.01em; margin: 0 0 1rem; color: var(--text-color);
}
.gc-public-page .gc-markdown h2 { font-weight: 600; font-size: 22px; margin: 2rem 0 .6rem; color: #f0f0f2; }
.gc-public-page .gc-markdown h3 { font-weight: 600; font-size: 18px; margin: 1.5rem 0 .4rem; color: #f0f0f2; }
.gc-public-page .gc-markdown h4 { font-weight: 600; font-size: 16px; margin: 1.25rem 0 .4rem; color: #e6e6e8; }
.gc-public-page .gc-markdown p { margin: 0 0 1.1rem; }
.gc-public-page .gc-markdown ul, .gc-public-page .gc-markdown ol { margin: 0 0 1.1rem; padding-left: 1.3rem; }
.gc-public-page .gc-markdown li { margin: .35rem 0; }
.gc-public-page .gc-markdown a { color: var(--tertiary-color); }
.gc-public-page .gc-markdown hr { border: 0; border-top: 1px solid rgba(255,255,255,.10); margin: 2rem 0; }
.gc-public-page .gc-markdown img { max-width: 100%; height: auto; display: block; margin: 1.5rem 0; }
.gc-public-page .gc-markdown video { max-width: 100%; height: auto; display: block; margin: 1.5rem 0; border-radius: 8px; }
.gc-public-page .gc-markdown table { border-collapse: collapse; width: 100%; margin: 1.25rem 0; }
.gc-public-page .gc-markdown th, .gc-public-page .gc-markdown td {
  border: 1px solid rgba(255,255,255,.12); padding: .5rem .7rem; text-align: left;
}
.gc-public-page .gc-markdown th { background: rgba(255,255,255,.04); font-weight: 600; }
/* Headerless tables. Markdown has no way to write a table without a header row,
   so a term/definition table is authored with an empty one (`|  |  |`) and would
   otherwise render as a blank shaded band above the first term. Hide a thead only
   when *every* th in it is empty, so a real header is never touched.
   Both renderers emit truly empty `<th></th>` for that row — python-markdown on
   the Flask route and marked in the dcc.Markdown twin — so one rule covers both.
   Unsupported :has() just leaves the band visible, which is the status quo. */
.gc-markdown thead:not(:has(th:not(:empty))) { display: none; }
/* Public footer styling now lives in the shared "Footer" block above
   (grouped .gc-app-footer / .gc-public-footer selectors + context modifiers). */

/* --- landing page (body.gc-landing) --- */
body.gc-landing { background: var(--surface-page, #17171f);
  font-family: var(--bs-body-font-family, "Roboto", system-ui,
    -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif); }
.gc-lp { max-width: var(--gc-public-max); margin: 0 auto; padding: 0 1rem 4rem;
  color: var(--text-color, #dadada); }
.gc-lp h1, .gc-lp h2 { letter-spacing: -.01em; }
.gc-lp-hero { display: grid; grid-template-columns: 1fr 1fr; gap: 2.5rem;
  align-items: center; padding: 3.5rem 0 3rem; }
.gc-lp-hero-copy h1 { font-size: clamp(2rem, 4vw, 3rem); line-height: 1.1;
  letter-spacing: -.02em; font-weight: 700; color: var(--text-color); margin: 0 0 1rem; }
.gc-lp-lede { font-size: 17px; line-height: 1.6; color: #c9c9cf;
  margin: 0 0 1.75rem; max-width: 36ch; }
.gc-lp-actions { display: flex; align-items: center; gap: 1.25rem; margin: 0; }
.gc-lp-actions--center { justify-content: center; }
.gc-lp-cta { display: inline-block; background: #ffffff; color: #121212;
  font-weight: 600; padding: .7rem 1.5rem; text-decoration: none;
  border: 1px solid var(--text-color); transition: filter .15s ease; }
.gc-lp-cta:hover { filter: brightness(0.92); text-decoration: none; color: #111117; }
.gc-lp-signin { color: #c9c9cf; font-size: var(--gc-public-font); }
.gc-lp-media { display: flex; align-items: center; justify-content: center;
  min-height: 240px; padding: 1rem; text-align: center;
  background: var(--surface-raised, #282834);
  border: 1px solid rgba(255,255,255,.08); }
.gc-lp-media--hero { min-height: 300px; }
.gc-lp-media-label { color: var(--inactive-text-color); font-size: .9rem; max-width: 26ch; }
.gc-lp-media-img { width: 100%; height: auto; display: block; }
.gc-lp-band { padding: 1rem 0 1.5rem; }
.gc-lp-band-img { width: 100%; height: auto; display: block; }
.gc-lp-band-cap { color: var(--inactive-text-color); font-size: .9rem; text-align: center;
  margin: .75rem 0 0; }
.gc-lp-row { display: grid; grid-template-columns: 1fr 1fr; gap: 2.5rem;
  align-items: center; padding: 2.75rem 0;
  border-top: 1px solid rgba(255,255,255,.08); }
.gc-lp-row--reverse { direction: rtl; }
.gc-lp-row--reverse > * { direction: ltr; }
.gc-lp-row-copy h2 { font-size: 1.6rem; font-weight: 600; color: #f0f0f2;
  margin: 0 0 .6rem; }
.gc-lp-row-copy p { color: #c9c9cf; line-height: 1.65; margin: 0 0 .9rem;
  font-size: var(--gc-public-font); }
.gc-lp-link { color: var(--tertiary-color); text-decoration: none; font-weight: 500; }
.gc-lp-closing { text-align: center; padding: 3.5rem 0 1rem; margin-top: 1rem;
  border-top: 1px solid rgba(255,255,255,.08); }
.gc-lp-closing h2 { color: var(--text-color); font-size: 1.8rem; margin: 0 0 1.25rem; }
.gc-lp-closing p { margin: 0 0 1rem; }
.gc-lp-closing-sub { color: #c9c9cf; font-size: var(--gc-public-font); }
.gc-lp-closing-sub a { color: var(--tertiary-color); }
@media (max-width: 720px) {
  .gc-lp-hero, .gc-lp-row { grid-template-columns: 1fr; gap: 1.5rem;
    padding: 2rem 0; }
  .gc-lp-row--reverse { direction: ltr; }
}


/* SEE ALSO
 *
 * zstyles.css
 *
 * used to resolve load-order issued
 *
 */
