/*
 * The product's own surfaces: the route bar, the month price grid, the alert rows and the console.
 *
 * A file of its own rather than more of 04-components.css, because these are not generic pieces a
 * second product would reuse -- they are this app's one screen. 04 stays the answer to "is there
 * already a component for this"; 07 is the answer to "how does the fare grid work".
 *
 * Sorts after 06-marketing.css, so it can lean on the page frame without fighting it.
 */

/* ------------------------------------------------------------ Route bar ---- */
/* Where the reader says what they are looking at: two selects and the one number that makes the
   whole product's case. Wrapping flex rather than a grid, because the stat card should drop to its
   own line before the two selects squeeze below readable. */
.route-bar { display: flex; flex-wrap: wrap; gap: 10px; align-items: stretch; }

/* margin is RESET, not omitted. This is a <label>, and 04-components.css gives every label
   `margin-bottom: 6px` -- correct for a label sitting above an input, wrong for one that IS the
   box. As a stretched flex item the margin comes off the bottom, so the two selects rendered 6px
   shorter than the trip toggle and the price beside them. Same trap as .route-stat being a <p>:
   an element used as a layout box has to say so, and spec/system/layout_boxes_spec.rb walks every
   flex row on the page looking for the next one. */
.route-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin: 0;
  background: var(--field);
  border: 1px solid var(--line2);
  border-radius: var(--r-card);
  padding: 10px 14px;
  min-width: 150px;
  flex: 1 1 150px;
  cursor: pointer;
}
.route-field:focus-within { border-color: var(--accent); }
.route-field__label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--text-4);
}
/* appearance:none, then the caret is drawn back on the wrapper. A native select arrow inside a
   bordered card reads as a second, competing border on every platform. */
.route-field select {
  appearance: none;
  background: transparent;
  border: 0;
  outline: none;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 16px;
  font-weight: 600;
  padding: 0;
  width: 100%;
  cursor: pointer;
}
.route-field select option { background: var(--field); color: var(--text); }

/* Under 420px the two selects stop sharing a row.
   At 360px each field is about 159px wide, and "Ponta Delgada PDL" does not fit in it -- a select
   clips rather than wrapping or ellipsing, so the destination silently read "Ponta Delgada PD".
   Stacking is the honest fix: the label is the thing that must stay readable. */
@media (max-width: 419px) {
  .route-field { flex: 1 1 100%; }
}

/* The headline number. Accent FILL, so it carries --on-accent as its ink.
   margin and max-width are RESET, not omitted: this is a <p>, and 02-base.css gives every
   paragraph `margin: 0 0 1em` and `max-width: var(--measure)`. Both are wrong for a box that is a
   flex item -- the margin eats 1em off the bottom of a stretched item, so the green card sat
   shorter than the two selects beside it, and the 640px cap stops it growing with them on a wide
   screen. Any <p> used as a layout box has to say so. */
.route-stat {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  margin: 0;
  max-width: none;
  background: var(--accent);
  color: var(--on-accent);
  border-radius: var(--r-card);
  padding: 10px 20px;
  flex: 1 1 190px;
}
.route-stat__label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  opacity: 0.72;
}
.route-stat__value {
  font-family: var(--font-mono);
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.03em;
}
.route-stat__when { font-size: 13px; font-weight: 500; letter-spacing: normal; }

/* One choice with two states, dressed as a route field so the bar stays one row of equal boxes.
   A fieldset, because that is what a radio group is; the browser's default border, padding and
   min-inline-size all have to be turned off before it will behave like a flex item. */
.trip-toggle {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  padding: 9px 14px;
  border: 1px solid var(--line2);
  border-radius: var(--r-card);
  background: var(--field);
  flex: 1 1 190px;
  min-inline-size: 0;
}
/* float, because a <legend> is not a flex item: left where it is, the browser lifts it out of the
   fieldset's flow and hangs it in the top border. Floating puts it back in the box. */
.trip-toggle__legend {
  float: left;
  width: 100%;
  padding: 0;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--text-4);
}
.trip-toggle__options { display: flex; flex-wrap: wrap; gap: 6px; clear: both; }

.trip-toggle__option {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* POSITIONED, so the visually-hidden radio inside is absolute against THIS label rather than
     against whatever positioned ancestor it can find. Without it the input escaped to .page and sat
     at the very top of the document, so clicking the pill focused a control 1,500px away and the
     browser scrolled there: the page appeared to jump to the top on every trip change. */
  position: relative;
  margin: 0;                 /* a <label> again; see .route-field */
  padding: 6px 13px;
  border: 1px solid var(--line3);
  border-radius: var(--r-pill);
  color: var(--text-3);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--motion), color var(--motion), border-color var(--motion);
}
.trip-toggle__option:hover { color: var(--text); border-color: var(--accent-70); }
.trip-toggle__option.is-active {
  background: var(--moss);
  color: var(--on-moss);
  border-color: transparent;
}

/* Hidden from sight, NOT from the keyboard or a screen reader: clip rather than display:none, so
   the radio still takes focus and still announces its group. The ring is drawn on the label. */
.trip-toggle__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.trip-toggle__input:focus-visible + span {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: var(--r-pill);
}

/* Under 420px the toggle takes a row of its own rather than squeezing beside a select. */
@media (max-width: 419px) {
  .trip-toggle { flex: 1 1 100%; }
}

/* ---------------------------------------------------------- Month strip ---- */
/* Six months, always. A month we hold nothing for keeps its place and shows an em dash -- dropping
   it would shorten the row and quietly change what the reader is comparing.
 
   THE SIX SHARE THE ROW. Sized to their own text they came out 72-75px each and clustered at the
   left of a 1116px container, under a full-width route bar and above a full-width grid -- a short
   ragged row that read as a mistake. `flex: 1 1 0` on the item makes them equal and makes the row
   span its container, and the min-width is what makes the same rule scroll on a narrow screen
   instead of crushing six months into 358px. One rule, both behaviours, no breakpoint. */
.month-strip {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 12px;
  scrollbar-width: thin;
  margin: 0;
  list-style: none;
}
/* The <li> is the flex item, not the chip inside it. Putting flex on .month-chip did nothing at
   all, which is half of why the row was ragged. */
.month-strip > li {
  display: flex;
  flex: 1 1 0;
  min-width: 96px;
}

/* The edge fades, drawn only on a side that really has more (scroll_hint_controller.js). A
   permanent fade would be a lie on a desktop, where the row fits. */
.month-strip.has-more-before { mask-image: linear-gradient(to right, transparent, #000 28px); }
.month-strip.has-more-after { mask-image: linear-gradient(to left, transparent, #000 28px); }
.month-strip.has-more-before.has-more-after {
  mask-image: linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent);
}

.month-chip {
  display: flex;
  flex-direction: column;
  gap: 3px;
  align-items: flex-start;
  justify-content: center;
  width: 100%;
  padding: 10px 16px;
  border-radius: var(--r-card);
  cursor: pointer;
  background: var(--surface);
  border: 1px solid var(--line1);
  color: var(--text-3);
  transition: border-color var(--motion), color var(--motion), background var(--motion);
  min-height: 44px;
}
.month-chip:hover { border-color: var(--line3); color: var(--text); }
.month-chip__label { font-size: 13px; font-weight: 600; letter-spacing: -0.01em; }
.month-chip__price { font-family: var(--font-mono); font-size: 15px; font-weight: 700; }
.month-chip.is-active {
  background: var(--field-hi);
  border-color: var(--accent-70);
  color: var(--text);
}

/* ----------------------------------------------------------- Month grid ---- */
.month-grid {
  background: var(--surface);
  border: 1px solid var(--line1);
  border-radius: var(--r-panel);
  padding: clamp(14px, 2.6vw, 26px);
}
.month-grid__head {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 18px;
}
.month-grid__heading { display: flex; align-items: center; gap: 10px; min-width: 0; }
.month-grid__title { margin: 0; font-size: clamp(20px, 3vw, 26px); font-weight: 800; letter-spacing: -0.025em; }

/* One month back, one month forward. 44px because it is a hit target on a phone, and a circle
   because the two of them flank the heading and a pair of rectangles there reads as tabs. */
.month-step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line2);
  color: var(--text-3);
  font-size: 17px;
  line-height: 1;
  transition: border-color var(--motion), color var(--motion), background var(--motion);
}
.month-step:hover { border-color: var(--accent-70); color: var(--text); background: var(--field); }
/* Kept in place rather than removed at the ends of the range: an arrow that disappears shifts the
   heading under the reader's cursor. --text-5 is ornament-only, which is exactly what this is. */
.month-step.is-disabled { color: var(--text-5); border-color: var(--line1); cursor: default; }
.month-grid__legend {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-3);
  margin: 0;
  list-style: none;
  padding: 0;
}
.month-grid__legend li { display: flex; align-items: center; gap: 6px; }
.swatch { width: 10px; height: 10px; border-radius: 3px; display: inline-block; flex: none; }
.swatch--cheap { background: var(--accent); }
.swatch--average { background: var(--accent-24); }
.swatch--high { background: var(--line1); }

/* The grid SCALES rather than scrolls. Seven columns of minmax(0,1fr) with a clamped gap holds its
   shape to 360px; a horizontally scrolling calendar is a calendar you cannot scan, which is the
   one thing this screen exists to let you do. */
.month-grid__days,
.month-grid__week {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: clamp(4px, 0.7vw, 8px);
}
.month-grid__days { margin-bottom: 8px; }
.month-grid__day-name {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--text-4);
  text-align: center;
  padding-bottom: 2px;
}
.month-grid__weeks { display: grid; gap: clamp(4px, 0.7vw, 8px); }

.day-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  aspect-ratio: 1 / 0.86;
  border-radius: var(--r-cell);
  padding: 2px;
  border: 1px solid transparent;
  background: transparent;
  font-family: var(--font-sans);
  cursor: pointer;
  transition: transform 120ms ease, border-color var(--motion);
  width: 100%;
}
.day-cell:hover { transform: translateY(-1px); }
.day-cell__date {
  font-family: var(--font-mono);
  font-size: clamp(9px, 1.15vw, 11px);
  line-height: 1;
  opacity: 0.72;
}
.day-cell__price {
  font-family: var(--font-mono);
  font-size: clamp(11px, 1.7vw, 16px);
  font-weight: 700;
  line-height: 1;
}

/* The three tiers, relative to the month on screen. */
.day-cell--cheap { background: var(--accent); color: var(--on-accent); }
.day-cell--average { background: var(--accent-20); color: var(--accent-ink); border-color: var(--line1); }
.day-cell--high { background: var(--line1); color: var(--text-3); border-color: var(--line1); }

/* A day we hold no price for. Dashed and unclickable, so the absence reads as "not offered"
   rather than as "free". */
.day-cell--empty {
  border: 1px dashed var(--line1);
  color: var(--text-5);
  cursor: default;
}
.day-cell--empty:hover { transform: none; }
/* Padding cells exist only to keep the grid rectangular. */
.day-cell--outside { visibility: hidden; }

/* A price the airline has not reconfirmed inside a week. It stays on the grid -- removing it would
   be the quietest kind of lie -- but it is struck through so no one reads it as current. */
.day-cell--stale .day-cell__price { text-decoration: line-through; opacity: 0.7; }

/* The selected day. A NEUTRAL ring, because the selected cell is usually the cheapest one and a
   green ring on a green fill reads as nothing at all. */
.day-cell.is-selected {
  border: 2px solid var(--moss-strong);
  box-shadow: 0 0 0 4px var(--moss-22);
}

/* ------------------------------------------------------------ Detail bar --- */
.day-detail {
  margin-top: 18px;
  border-top: 1px solid var(--line1);
  padding-top: 16px;
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
}
.day-detail__facts { display: flex; flex-wrap: wrap; gap: 6px 22px; align-items: baseline; }
.day-detail__date { font-size: 17px; font-weight: 700; letter-spacing: -0.02em; }
.day-detail__price { font-family: var(--font-mono); font-size: 22px; font-weight: 700; color: var(--accent-text); }
.day-detail__meta { font-size: 13px; color: var(--text-3); }
.day-detail__actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* The watch-this-date control. --moss rather than --accent so it does not compete with the
   cheapest cell sitting directly above it. */
.btn--moss {
  border: 1px solid var(--moss-50);
  background: var(--moss-16);
  color: var(--moss-text);
  font-size: 13px;
  font-weight: 600;
  padding: 9px 16px;
  border-radius: var(--r-pill);
}
.btn--moss:hover { background: var(--moss-30); color: var(--moss-text); border-color: var(--moss-50); }

/* ---------------------------------------------------------- Shared bits ---- */
/* The mono uppercase label above a group of controls. The one place the mono face still does what
   it used to do on buttons: mark something as a label rather than as prose. */
.field-label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  color: var(--text-4);
  margin: 0 0 9px;
  text-transform: uppercase;
}

.pill-row { display: flex; flex-wrap: wrap; gap: 6px; }

/* The round control. Filled when chosen, outlined when not. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 14px;
  border-radius: var(--r-pill);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  background: transparent;
  color: var(--text-3);
  border: 1px solid var(--line3);
  transition: background var(--motion), border-color var(--motion), color var(--motion);
  min-height: 44px;
}
.pill:hover { color: var(--text); border-color: var(--accent); }
.pill.is-active {
  background: var(--moss);
  color: var(--on-moss);
  border-color: transparent;
}

/* A pill wrapping a real checkbox or radio. The input is the accessible control and the pill is
   its label -- so :has() paints the state rather than a class the server has to keep in step. */
.pill--check input { position: absolute; opacity: 0; width: 0; height: 0; }
.pill--check:has(input:checked) {
  background: var(--accent);
  color: var(--on-accent);
  border-color: transparent;
}
.pill--check:has(input:focus-visible) { outline: 2px solid var(--accent-text); outline-offset: 2px; }

/* A channel that cannot reach anyone yet. Offered rather than hidden: it says the product can do
   this and what is missing. */
.pill--disabled {
  color: var(--text-4);
  border-style: dashed;
  cursor: default;
  font-weight: 500;
}
.pill--disabled:hover { color: var(--text-4); border-color: var(--line3); }
a.pill--disabled { cursor: pointer; }
a.pill--disabled:hover { color: var(--accent-text); border-color: var(--accent); }

.field-input {
  flex: 1 1 180px;
  background: var(--field);
  border: 1px solid var(--line2);
  border-radius: var(--r-input);
  padding: 13px 15px;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 15px;
  outline: none;
  min-height: 44px;
}
.field-input:focus { border-color: var(--accent); }

/* --------------------------------------------------------- Trigger form --- */
.trigger { display: flex; flex-direction: column; gap: 16px; }
.trigger__note { margin: 0; font-size: 13px; line-height: 1.55; color: var(--text-3); }

.threshold { display: flex; flex-direction: column; gap: 8px; }
.threshold__head { display: flex; justify-content: space-between; align-items: baseline; }
.threshold__label { font-size: 14px; color: var(--text-2); }
.threshold__value { font-family: var(--font-mono); font-size: 24px; font-weight: 700; color: var(--accent-text); }
.threshold input[type="range"] { width: 100%; height: 4px; accent-color: var(--accent); }
.threshold__bounds {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-4);
  margin: 0;
}

.date-pair { display: flex; gap: 10px; flex-wrap: wrap; }
.date-field {
  flex: 1 1 130px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  background: var(--field);
  border: 1px solid var(--line2);
  border-radius: var(--r-input);
  padding: 9px 12px;
}
.date-field .field-label { margin: 0; }
/* color-scheme on :root is what makes the native picker follow the theme. Without it a light-theme
   page opens a dark date picker on a dark-preferring OS. */
.date-field input {
  background: transparent;
  border: 0;
  outline: none;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  width: 100%;
  min-height: 28px;
}

.delivery { display: flex; flex-direction: column; gap: 16px; }

/* ------------------------------------------------------------ Alert rows --- */
.alert-row {
  background: var(--surface);
  border: 1px solid var(--line1);
  border-radius: var(--r-row);
  overflow: hidden;
  transition: border-color var(--motion);
}
.alert-row[open] { border-color: var(--moss-50); }
.alert-row--paused { opacity: 0.72; }

.alert-row__head {
  list-style: none;
  cursor: pointer;
  padding: clamp(14px, 2.2vw, 20px);
  display: flex;
  flex-wrap: wrap;
  gap: 12px 18px;
  align-items: center;
  justify-content: space-between;
}
/* Safari draws its own disclosure triangle through ::-webkit-details-marker, which list-style
   alone does not remove. */
.alert-row__head::-webkit-details-marker { display: none; }
.alert-row__head::before {
  content: "▸";
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-4);
  flex: none;
}
.alert-row[open] .alert-row__head::before { content: "▾"; }

.alert-row__identity { display: flex; flex-direction: column; gap: 4px; min-width: 0; margin-right: auto; }
.alert-row__route { font-size: 17px; font-weight: 700; letter-spacing: -0.02em; }
.alert-row__rule { font-size: 13px; color: var(--text-3); }

.alert-row__status { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.alert-row__figures { display: flex; flex-direction: column; gap: 3px; text-align: right; }
.alert-row__floor { font-family: var(--font-mono); font-size: 17px; font-weight: 700; color: var(--accent-text); }
.alert-row__hits { font-size: 11px; color: var(--text-4); }

.status-pill {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  padding: 4px 9px;
  border-radius: var(--r-pill);
  background: var(--line1);
  color: var(--text-4);
}
.status-pill--on { background: var(--accent-18); color: var(--accent-text); }

.alert-row__body { border-top: 1px solid var(--line1); padding: clamp(14px, 2.2vw, 22px); }
.alert-row__form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 22px;
  align-items: start;
}
.alert-row__col { display: flex; flex-direction: column; gap: 16px; }
.alert-row__actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 18px; }
.alert-row__actions form { margin: 0; }

/* ---------------------------------------------------------- Hero + bands --- */
.hero__title {
  font-size: clamp(38px, 7.4vw, 76px);
  line-height: 0.94;
  letter-spacing: -0.035em;
  font-weight: 800;
  margin: 0 0 20px;
  max-width: 15ch;
  text-wrap: balance;
}
.hero__lede {
  font-size: clamp(16px, 2.2vw, 20px);
  line-height: 1.5;
  color: var(--text-3);
  max-width: 52ch;
  margin: 0 0 32px;
}

/* The honest empty state. A month with no fares says so in a sentence, rather than showing an
   empty grid that reads as a bug. */
.empty-note { margin: 16px 0 0; font-size: 15px; line-height: 1.6; color: var(--text-3); max-width: 60ch; }

/* ------------------------------------------------------- Subscribe band ---- */
/* auto-fit minmax is what makes this one column at 360px and two on a laptop with no breakpoint of
   its own. */
.alerts-band {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(24px, 4vw, 48px);
  align-items: start;
}
.alerts-band__copy { min-width: 0; }
.alerts-band__title {
  font-size: clamp(28px, 4.6vw, 44px);
  line-height: 1.02;
  letter-spacing: -0.03em;
  font-weight: 800;
  margin: 0 0 16px;
  max-width: 16ch;
}
.alerts-band__lede { font-size: 16px; line-height: 1.6; color: var(--text-3); max-width: 44ch; margin: 0 0 22px; }

.dotted-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 12px; }
.dotted-list li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  font-size: 14px;
  color: var(--text-2);
  line-height: 1.5;
}
.dotted-list li::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  margin-top: 7px;
  flex: none;
}

.subscribe-card {
  background: var(--surface);
  border: 1px solid var(--line2);
  border-radius: var(--r-panel);
  padding: clamp(18px, 3vw, 28px);
}
.subscribe-form { display: flex; flex-direction: column; gap: 18px; }
.subscribe-form__submit { display: flex; gap: 8px; flex-wrap: wrap; }
.subscribe-form__summary { margin: 0; font-size: 12px; color: var(--text-4); line-height: 1.5; }

/* The price, stated where the commitment is made. Ruled off above rather than boxed: it belongs to
   the button below it, not to the controls above. */
.subscribe-price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  margin: 0;
  padding-top: 16px;
  border-top: 1px solid var(--line1);
  font-size: 14px;
  line-height: 1.5;
}
.subscribe-price__amount { font-family: var(--font-mono); font-weight: 700; color: var(--text); }
.subscribe-price__note { color: var(--text-3); }
.subscribe-price__link { margin-left: auto; font-size: 13px; font-weight: 600; white-space: nowrap; }

.subscribe-done { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; }
.subscribe-done__check {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: 800;
  margin: 0;
}
.subscribe-done__title { margin: 0; font-size: 22px; font-weight: 800; letter-spacing: -0.02em; }
.subscribe-done__rule { margin: 0; font-size: 15px; line-height: 1.55; color: var(--text-2); }
.subscribe-done__meta { margin: 0; font-family: var(--font-mono); font-size: 12px; color: var(--text-4); }

/* -------------------------------------------------------- Console band ----- */
/* The signed-in console. --sunk rather than --bg, so the band reads as a floor the alerts sit on
   rather than as one more section of the marketing page above it. */
.console-band {
  background: var(--sunk);
  border-top: 1px solid var(--line1);
}
/* .page-inner supplies the horizontal gutter; this adds only the vertical rhythm, because the band
   is rendered outside the container and cannot inherit .band's padding. */
.console-band__inner { padding-block: clamp(36px, 6vw, 72px); }
.console-band__head {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 26px;
}
.console-band__account { margin: 0; font-size: 15px; color: var(--text-3); }
.console-band__actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

.alert-stack { display: flex; flex-direction: column; gap: 12px; }

/* ------------------------------------------------------------ Console page -- */
.tab-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 24px; }
.tab-row .pill.is-active { background: var(--field-hi); color: var(--text); border-color: var(--moss-50); }

.account-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px;
  align-items: start;
}
.account-column { display: flex; flex-direction: column; gap: 12px; }

.account-card {
  background: var(--surface);
  border: 1px solid var(--line1);
  border-radius: var(--r-row);
  padding: clamp(16px, 2.4vw, 24px);
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.account-card__head {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
}
.account-card__title { margin: 0; font-size: 18px; font-weight: 800; letter-spacing: -0.02em; }
.account-card__renewal { margin: 0; font-family: var(--font-mono); font-size: 12px; color: var(--text-3); }
.account-card__actions { display: flex; gap: 8px; flex-wrap: wrap; }
.account-card__actions form { margin: 0; }

/* 150px, not 180: the console's account column is about 340px wide inside its padding, and at
   180 the two plan cards wrapped to one column on every laptop rather than only on a phone. */
.plan-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.plan-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
  text-align: left;
  padding: 18px;
  border-radius: var(--r-card);
  cursor: pointer;
  background: var(--plan-idle);
  border: 1px solid var(--line2);
  color: var(--text);
  width: 100%;
  font-family: var(--font-sans);
}
.plan-card--current { background: var(--plan-on); border-color: var(--accent-70); cursor: default; }
.plan-card__badge {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  padding: 4px 9px;
  border-radius: var(--r-pill);
  background: var(--line1);
  color: var(--text-3);
}
.plan-card--current .plan-card__badge { background: var(--accent); color: var(--on-accent); }
.plan-card__price { font-family: var(--font-mono); font-size: 24px; font-weight: 700; letter-spacing: -0.02em; }
.plan-card__line { font-size: 13px; color: var(--text-3); line-height: 1.45; }
.plan-cards form { margin: 0; display: contents; }

.invoice-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.invoice {
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  border-top: 1px solid var(--line1);
  padding-top: 10px;
  margin-top: 10px;
}
.invoice__what { display: flex; flex-direction: column; gap: 2px; }
.invoice__date { font-size: 14px; font-weight: 600; }
.invoice__label { font-size: 12px; color: var(--text-4); }
.invoice__how-much { display: flex; align-items: center; gap: 14px; }
.invoice__amount { font-family: var(--font-mono); font-size: 14px; }
.invoice__receipt { font-size: 12.5px; font-weight: 600; }

.settings-form { display: flex; flex-direction: column; gap: 12px; }
.field-select {
  background: transparent;
  border: 0;
  outline: none;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 600;
  width: 100%;
  min-height: 28px;
}

.switch-row { display: flex; gap: 14px; align-items: center; justify-content: space-between; }
.switch-row__label { font-size: 14px; color: var(--text-2); line-height: 1.45; }

/* A real checkbox under a painted track. :has() paints the state, so the input stays the
   accessible control rather than being reimplemented by a div with a click handler. */
.switch { position: relative; flex: none; cursor: pointer; display: inline-flex; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch__track {
  width: 46px;
  height: 26px;
  border-radius: var(--r-pill);
  background: var(--line3);
  display: block;
  transition: background var(--motion);
}
.switch__knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--text);
  transition: left 160ms ease;
}
.switch:has(input:checked) .switch__track { background: var(--accent); }
.switch:has(input:checked) .switch__knob { left: 23px; }
.switch:has(input:focus-visible) .switch__track { outline: 2px solid var(--accent-text); outline-offset: 2px; }

.channel-setup {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  border-top: 1px solid var(--line1);
  padding-top: 14px;
}
.channel-setup form { margin: 0; display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.channel-setup__form { flex: 1 1 100%; }
.channel-setup__state { margin: 0; font-size: 13px; color: var(--text-3); flex: 1 1 100%; }
