/* Landing — the public front door (homepage redesign §2–§3).
 *
 * The owner-approved homepage redesign (docs/design/homepage-redesign.md,
 * pixel spec docs/design/mockups/mockups.css): the "Where the money moved"
 * sector panel at the top — the page's one bold element — then "The
 * published dashboard" (summary strip + hairline table + quiet compare
 * link), the sign-up band, the three feature notes and the footer. No
 * marketing hero: the sector sentence is the headline. The app's TopBar
 * frames the page and carries the Login action.
 *
 * Only rules styles.css does not already paint. Colour, type, spacing,
 * radius and motion come only from tokens.css custom properties: no hex,
 * rgb()/hsl() or named colour literal lives here (transparent, currentColor
 * and inherit are allowed), and no raw length equals a token value. The
 * few design sizes without a token of their own (34px display, 19px title,
 * 15px body, 210px name column, the 10px bar, the 26px track) use raws the
 * token gate allows or a token-sized calc — see the comments at each rule.
 *
 * Direction colour: BARS use --up/--down (graphics); signed TEXT uses
 * --pos/--neg, the AA text derivations — never the raw bar colours.
 *
 * Loaded by views/landing.js, which appends one <link> to <head> on mount.
 */

/* ---- page frame ----------------------------------------------------------- */

.landing {
  flex: 1;
  box-sizing: border-box;
  width: 100%;
  max-width: 1120px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  padding: 0 var(--space-6);
}

/* ---- "Where the money moved" — the sector hero panel ------------------------
   The sector trading activity panel (views/sector-hero.js) at the TOP of
   the page, above the published dashboard: a flat panel with a hairline
   border and 32px padding — no shadow — carrying the generated sentence at
   display size, the quiet window switch and the diverging bars. */

.landing-sector {
  display: contents;
}

.sh {
  margin-top: var(--space-4);
  padding: var(--space-7);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.sh-head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: var(--space-4);
}

.sh-kicker {
  grid-column: 1;
  grid-row: 1;
  margin: 0;
  font-size: var(--fs-small);
  color: var(--text-muted);
}

/* The window switch at the panel's top right, quieter than the shared box:
   hairline track on the panel, small sentence-case tabs; the selected tab
   takes the accent tint with its label in accent (500). */
.sh-seg {
  grid-column: 2;
  grid-row: 1;
  justify-self: end;
}

.sh-seg .tabs {
  gap: 2px;
  border-color: var(--border);
  background: none;
}

.sh-seg .tab {
  padding: 5px var(--space-3);
  font-weight: var(--fw-regular);
}

.sh-seg .tab[aria-selected="true"] {
  background: var(--accent-tint);
  color: var(--accent);
  font-weight: var(--fw-medium);
  box-shadow: none;
}

/* The one bold element: the generated sentence, at the design's display
   size (34px/1.18, 600 — 25px on phones). Sentence case, plain text. */
.sh-headline {
  grid-column: 1 / -1;
  grid-row: 2;
  margin: var(--space-3) 0 0;
  max-width: 21em;
  font-size: 34px;
  line-height: 1.18;
  letter-spacing: -0.012em;
  font-weight: var(--fw-semibold);
  color: var(--text);
  text-wrap: balance;
}

/* Loading: a quiet skeleton line where the sentence will land. */
.sh-skeleton-line {
  display: block;
  width: 60%;
  height: 1em;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}

/* The chart block sits on the panel's content edge (the old centred 880px
   block is gone): 32px under the headline block — the flex gap supplies
   16px of it — and the bars run from the panel's left edge to its right. */
.sh-chart {
  margin-top: var(--space-4);
}

.sh-rows {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* One row: the plain sector name + ticker secondary, right-aligned against
   the bar area (210px — the longest sector name keeps every letter), then
   the diverging bar from the centred zero line. Bars may reach 30% of the
   track per side (--sh-span); the bar length and the value's place at its
   end read ONE row custom property (--sh-r, the row's share of the biggest
   bar). The value lands at the bar end with tabular figures and a sign —
   sans, never mono. */
.sh-row {
  --sh-span: 30%;
  --sh-gap: calc(var(--space-2) + 2px);
  --sh-r: 0;
  display: grid;
  grid-template-columns: 210px minmax(0, 1fr);
  align-items: center;
  column-gap: var(--space-4);
}

/* The rows are BUTTONS: activating one opens its hourly-volume popover.
   The UA's button paint is reset — the row keeps the chart's own look —
   and focus stays visible. */
button.sh-row {
  appearance: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: inherit;
  width: 100%;
  cursor: pointer;
}

button.sh-row:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.sh-row-label {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: var(--space-2);
  min-width: 0;
  text-align: right;
}

/* The full sector name, never truncated: the 210px name column is wide
   enough for the longest name, and a name may wrap inside the row instead
   of losing letters to an ellipsis. */
.sh-row-name {
  font-size: 15px;
  color: var(--text);
}

.sh-row-ticker {
  font-size: var(--fs-small);
  color: var(--text-muted);
  white-space: nowrap;
}

/* The track: 26px tall (space-6 + 2px) with a 1px zero line at its centre.
   Inflows run right, outflows run left. */
.sh-row-track {
  display: block;
  position: relative;
  height: calc(var(--space-6) + 2px);
}

.sh-row-track::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--border);
}

/* The bar: 10px tall (the 26px track minus 8px above and below), 3px
   corners. Bars are graphics — --up/--down. */
.sh-row-fill {
  position: absolute;
  inset-block: var(--space-2);
  width: calc(var(--sh-r, 0) * var(--sh-span));
  border-radius: 3px;
}

.sh-row-fill.is-up {
  left: 50%;
  background: var(--up);
  transform-origin: left center;
}

.sh-row-fill.is-down {
  right: 50%;
  background: var(--down);
  transform-origin: right center;
}

.sh-row-fill.is-flat {
  left: calc(50% - (var(--space-1) / 2));
  width: var(--space-1);
  background: var(--text-muted);
  transform-origin: center;
}

/* The value at the bar end: the bar's length plus one gap, measured from the
   centred zero line. Inflows reach right, outflows left, a flat row sits
   just beside the line. Signed values take the AA text derivations
   (--pos/--neg); a flat value stays quiet. */
.sh-row-value {
  position: absolute;
  inset-block: 0;
  display: flex;
  align-items: center;
  font-size: var(--fs-body);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
  color: var(--text-muted);
  white-space: nowrap;
}

.sh-row-value.is-up {
  left: calc(50% + var(--sh-r, 0) * var(--sh-span) + var(--sh-gap));
  color: var(--pos);
}

.sh-row-value.is-down {
  right: calc(50% + var(--sh-r, 0) * var(--sh-span) + var(--sh-gap));
  color: var(--neg);
}

.sh-row-value.is-flat {
  left: calc(50% + var(--sh-gap));
}

/* Loading rows: quiet skeleton blocks — no spinner, no colour. The label
   block hugs the bar area like the real names do. */
.sh-row.is-skeleton .sh-row-label {
  width: 40%;
  height: 1em;
  margin-left: auto;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}

.sh-row.is-skeleton .sh-row-track {
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}

.sh-row.is-skeleton .sh-row-track::before {
  background: transparent;
}

.sh-loading {
  font-size: var(--fs-small);
  color: var(--text-muted);
}

.sh-state[hidden] {
  display: none;
}

/* The stale qualification: a quiet notice ABOVE the bars, in --text-muted,
   only when the server flags the snapshot stale — the figures on the page
   are from an earlier time, never presented as current. The flex gap
   supplies its spacing (margin-block only, never a margin shorthand). */
.sh-stale {
  margin-block: 0;
  font-size: var(--fs-small);
  color: var(--text-muted);
}

.sh-stale[hidden] {
  display: none;
}

/* The footnote: what the numbers mean, the feed and the data time in ET —
   at meta size under a hairline (homepage-redesign.md §3). The flex gap
   supplies 16px of the 24px the design gives it above; the hairline and
   the 82ch measure are the design's own. */
.sh-footnote {
  margin: var(--space-2) 0 0;
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-subtle);
  max-width: 82ch;
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--text-muted);
}

/* One subtle bar grow-in on the first paint of real bars — the view adds
   .sh-anim exactly once, and never under reduced motion. */
@keyframes sh-grow {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

.sh-anim .sh-row-fill {
  animation: sh-grow var(--dur) ease-out both;
}

/* One subtle fade when data arrives after a loading state (T17) — added to
   the freshly painted content exactly once per arrival, and never under
   reduced motion. */
@keyframes sh-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.sh-fade {
  animation: sh-fade-in var(--dur) ease-out both;
}

@keyframes landing-fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.landing-fade {
  animation: landing-fade-in var(--dur) ease-out both;
}

@media (prefers-reduced-motion: reduce) {
  .sh-anim .sh-row-fill {
    animation: none;
  }

  .sh-fade,
  .landing-fade {
    animation: none;
  }
}

/* The calm 'Try again' button of the exhausted state (T17): under the
   honest sentence in the centred block, quiet like the rest of the panel. */
.sh-retry {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-block-start: var(--space-2);
}

/* The window switch stays VISIBLE but disabled while the snapshot loads
   (T17): quiet, but unmistakably inactive. */
.sh-seg .tab[disabled] {
  opacity: 0.5;
  cursor: default;
}

/* ---- "The published dashboard" (homepage-redesign.md §3) -------------------- */

.landing-volume-title {
  margin: 0 0 var(--space-2);
  font-size: 19px;
  line-height: 1.3;
  font-weight: var(--fw-semibold);
  color: var(--text);
}

.landing-volume-note {
  margin: 0 0 var(--space-6);
  max-width: 68ch;
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-muted);
}

/* Summary strip: three quiet columns on hairline rules — no cards. The
   figure size is the design's 20px; tokens.css has no 20px type token and
   --space-5 is its 20px value. */
.landing-summary {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: var(--space-5) 0;
}

.landing-summary:empty {
  display: none;
}

.landing-summary-col {
  padding-right: var(--space-6);
}

.landing-summary-col + .landing-summary-col {
  border-left: 1px solid var(--border-subtle);
  padding-left: var(--space-6);
}

.landing-summary-label {
  margin: 0 0 calc(var(--space-1) + 2px);
  font-size: var(--fs-small);
  color: var(--text-muted);
}

.landing-summary-symbol {
  font-size: 15px;
  font-weight: var(--fw-medium);
  color: var(--text);
  text-decoration: none;
}

.landing-summary-symbol:hover {
  text-decoration: underline;
}

.landing-summary-value {
  margin: 2px 0 var(--space-1);
  font-size: var(--space-5);
  font-weight: var(--fw-medium);
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.landing-summary-value.is-in {
  color: var(--pos);
}

.landing-summary-value.is-out {
  color: var(--neg);
}

.landing-summary-detail {
  margin: 0;
  font-size: var(--fs-small);
  color: var(--text-muted);
}

/* The table: hairline rules only, quiet sentence-case column labels,
   tabular right-aligned numbers, Day coloured by direction, the symbol
   column at 500. The shared DataTable paints the shell; these rules steer
   this page's copy of it (homepage-redesign.md §3). */
.landing-table {
  width: 100%;
  margin-top: var(--space-5);
}

/* The table is hidden (not emptied) while the public read fails, so the
 * recovery settles the next payload into the SAME table. */
.landing-table[hidden] {
  display: none;
}

.landing-table table.data thead th {
  background: var(--bg);
}

.landing-table table.data th {
  padding: calc(var(--space-2) + 2px) var(--space-3);
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  text-transform: none;
  letter-spacing: normal;
  color: var(--text-muted);
}

.landing-table table.data th.sortable {
  padding: 0;
}

.landing-table table.data th .sort-btn {
  padding: calc(var(--space-2) + 2px) var(--space-3);
}

.landing-table table.data td {
  padding: calc(var(--space-3) + 1px) var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
  font-size: 15px;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.landing-table table.data th:first-child,
.landing-table table.data td:first-child {
  padding-left: 0;
}

.landing-table table.data th:last-child,
.landing-table table.data td:last-child {
  padding-right: 0;
}

.landing-table table.data td:first-child {
  font-weight: var(--fw-medium);
}

.landing-table table.data td .is-in {
  color: var(--pos);
}

.landing-table table.data td .is-out {
  color: var(--neg);
}

/* The sideways-scroll hint names the phone table's off-screen columns
   (homepage-redesign.md:175, "(Volume / Avg volume scroll sideways)").
   Phone-only: the desktop table shows every column at once. */
.landing-scroll-hint {
  display: none;
}

/* The compare action: a quiet accent text link with an arrow. */
.landing-compare {
  display: inline-block;
  margin-top: var(--space-4);
  font-size: 15px;
  font-weight: var(--fw-medium);
  color: var(--accent);
  text-decoration: none;
}

/* The comparison link disappears when the published dashboard is empty —
 * and it must REALLY disappear: the rule above sets `display`, which would
 * otherwise beat the user agent's [hidden] rule. */
.landing-compare[hidden] {
  display: none;
}

.landing-loading {
  font-size: var(--fs-small);
  color: var(--text-muted);
}

/* The calm 'Try again' end of a spent warming retry budget (T17): the quiet
   sentence and a plain button — never an error banner. */
.landing-exhausted {
  font-size: var(--fs-small);
  color: var(--text-muted);
}

.landing-retry {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-block-start: var(--space-2);
}

/* Loading placeholders (T17): quiet skeleton blocks in --surface-2 where
   the real summary tiles and table rows will land — no fake values. The
   tile skeletons sit in the summary strip's own grid columns. */
.landing-card-skeleton {
  height: var(--space-9);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
}

.landing-rows-skeleton {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  width: 100%;
}

.landing-row-skeleton {
  height: var(--space-7);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}

/* The polite live regions (T17): visually hidden, but kept in the
 * accessibility tree at all times — never display:none or visibility:hidden
 * (review 3885#1). An empty region that is display:none is absent from the
 * a11y tree, so revealing it while setting its text does not reliably
 * announce; this pattern lets the region announce every text change. */
.landing-live,
.sh-live {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

/* ---- sign-up band (homepage-redesign.md §3) -------------------------------- */

.landing-invite {
  padding: 28px var(--space-7);
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
}

.landing-invite-title {
  margin: 0 0 var(--space-2);
  font-size: 19px;
  line-height: 1.3;
  font-weight: var(--fw-semibold);
  color: var(--text);
}

.landing-invite-note {
  margin: 0 0 var(--space-5);
  max-width: 58ch;
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-muted);
}

.landing-invite-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-5);
}

.landing-invite-actions .btn.primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: calc(var(--space-2) + 2px) 18px;
  border-radius: var(--radius-sm);
  font-size: 15px;
  font-weight: var(--fw-medium);
  text-decoration: none;
}

/* Review fix (Sol): the shared `.btn.primary:hover` brightness filter
 * lightens the accent under the text, which drops white-on-blue below AA in
 * light mode (4.16:1). These CTAs keep their rest-state paint on hover —
 * the filter is removed and hover is signalled by structure only: an
 * underline plus a border shift. Text contrast therefore stays at the
 * rest-state values, light 4.75:1 (white on --accent) and dark 7.00:1
 * (--accent-fg on --accent), in both states and both themes. */
.landing-invite .btn.primary:hover {
  filter: none;
  border-color: var(--accent-2);
  text-decoration: underline;
}

/* "Sign in" is the band's quiet text link. The mockup's var(--border-strong)
 * underline does not exist in tokens.css — the rendered mockup PNG shows a
 * plain currentColor underline, which is what this paints. */
.landing-invite-signin {
  font-size: 15px;
  font-weight: var(--fw-medium);
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---- feature strip (homepage-redesign.md §3) ------------------------------- */

.landing-points {
  border-top: 1px solid var(--border-subtle);
  padding-top: var(--space-6);
}

.landing-points-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-8);
}

.landing-point {
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-muted);
}

.landing-point-lead {
  display: block;
  margin: 0 0 calc(var(--space-1) + 2px);
  font-size: 15px;
  font-weight: var(--fw-semibold);
  color: var(--text);
}

/* ---- footer (homepage-redesign.md §3) -------------------------------------- */

.landing-footer {
  padding: var(--space-5) 0 var(--space-7);
  border-top: 1px solid var(--border-subtle);
}

.landing-footer-note {
  margin: 0;
  max-width: 72ch;
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--text-muted);
}

/* ---- phones (390; MOBILE_PLAN.md §3.7) --------------------------------------
   The page has no header of its own — the app's TopBar frames it — so the
   frame only clears the notch and the home indicator, and every account
   target takes the 44 px hit height. The rest of the phone layout follows
   the approved 390 mockup: 16px gutters (the shell's), stacked two-line
   sector rows, a one-column summary strip and feature notes, the volume
   columns of the table dropped, the window switch under the headline. */

@media (max-width: 767.98px) {
  /* Safe-area padding: 0 on desktop and on notchless phones (insets live in
     tokens.css only). */
  .landing {
    padding: 0;
    padding-block: var(--safe-top) var(--safe-bottom);
  }

  .landing-invite-actions .btn,
  .landing-invite-signin {
    display: inline-flex;
    align-items: center;
    min-height: var(--hit-min);
  }

  /* The hero panel: 20px padding, 24px under the TopBar (the shell frame
     supplies the other half of the mockup's 24px). */
  .sh {
    margin-top: var(--space-2);
    padding: var(--space-5);
  }

  .sh-head {
    display: flex;
    flex-direction: column;
    align-items: stretch;
  }

  .sh-headline {
    margin-top: calc(var(--space-2) + 2px);
    font-size: 25px;
  }

  .sh-seg {
    justify-self: auto;
    align-self: flex-start;
    margin-top: calc(var(--space-3) + 2px);
  }

  .sh-seg .tabs {
    display: inline-flex;
    width: auto;
  }

  .sh-seg .tab {
    flex: 0 1 auto;
    white-space: nowrap;
    min-height: 0;
    padding: 5px var(--space-3);
  }

  .sh-chart {
    margin-top: var(--space-2);
  }

  /* Two-line rows: the name + ticker line, then the bar under it — the
     eleven sectors and their values fit the 390px screen. */
  .sh-row {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 2px;
  }

  .sh-row-label {
    justify-content: flex-start;
    text-align: left;
    gap: var(--space-1);
  }

  /* Summary strip: one column, each tile on its own hairline. */
  .landing-summary {
    grid-template-columns: minmax(0, 1fr);
    padding: 0;
  }

  .landing-summary-col {
    padding: var(--space-4) 0;
    border-top: 1px solid var(--border-subtle);
  }

  .landing-summary-col:first-child {
    border-top: 0;
    padding-top: 0;
  }

  .landing-summary-col + .landing-summary-col {
    border-left: 0;
    padding-left: 0;
  }

  /* Every column stays in the phone table — the wireframe's "(Volume / Avg
     volume scroll sideways)" (homepage-redesign.md:171-175). The shared
     .table-wrap scrolls the overflow; the Symbol column stays pinned while
     it does, so a sideways scroll never loses the row names. */
  .landing-table table.data th:first-child,
  .landing-table table.data td:first-child {
    position: sticky;
    left: 0;
    background: var(--bg);
  }

  .landing-table table.data th:first-child {
    z-index: 2;
  }

  .landing-table table.data td:first-child {
    z-index: 1;
  }

  /* The pinned column follows the shared row hover/focus tint. */
  .landing-table table.data tbody tr:hover td:first-child,
  .landing-table table.data tbody tr:focus-within td:first-child {
    background: var(--panel-2);
  }

  /* The visible scroll hint (the wireframe's annotation), phone-only. */
  .landing-scroll-hint {
    display: block;
    margin-top: var(--space-2);
    font-size: var(--fs-small);
    color: var(--text-muted);
  }

  .landing-scroll-hint[hidden] {
    display: none;
  }

  .landing-invite {
    padding: var(--space-5);
  }

  /* Feature notes stack, each on its own hairline. */
  .landing-points-list {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  .landing-point {
    padding: var(--space-4) 0;
    border-top: 1px solid var(--border-subtle);
  }

  .landing-point:first-child {
    border-top: 0;
    padding-top: 0;
  }
}
