/* GoalSchema — the customer console.
   The console is served by InternalApp at goalschema.com/console (Laravel,
   resources/views/goalschema/console/*), but its look lives here, beside the
   rest of the brand, and ships with the storefront. It links three files in
   order: nocturne.css (tokens and components), site.css (the topbar, the
   footer, cards, tables, the plan cards) and this one, which adds only what a
   console has and the storefront does not: the sign-in card, the sub-nav, the
   alerts, the usage figures and chart, the key reveal and the keys table.

   Same rules as site.css: colours from the tokens or site.css's ground and
   line steps, never a new hex; style attributes carry custom properties only
   (--h, --w). Every class here starts cs-, so nothing on the storefront can
   pick one up by accident. The console's CSP is script-src 'none', so nothing
   here may depend on a script: the phone menu is a <details> whose open and
   closed rules sit in the layout itself, next to that markup. */

/* ── Topbar: the signed-in account ───────────────────────────────────────── */
.cs-who {
  max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--mono); font-size: 12.5px; color: var(--muted);
}
.cs-out { margin: 0; }
/* The phone menu's sign-out is a form button dressed as one of its links. */
.cs-m-out { margin: 0; }
.cs-m-out button {
  -webkit-appearance: none; appearance: none; width: 100%; border: 0; background: none; cursor: pointer;
  text-align: left; padding: 0; font-family: var(--sans);
}
.cs-m-who { display: flex; align-items: center; min-height: 52px; font-family: var(--mono); font-size: 13px; color: var(--muted); overflow-wrap: anywhere; box-shadow: inset 0 -1px 0 rgba(237, 238, 245, .07); }

/* ── Page head and sub-nav (signed in) ───────────────────────────────────── */
/* The storefront's page head, glow and all, set tighter: a console page is
   read for its figures, not its heading. */
.page-head.cs-head { padding: clamp(40px, 5vw, 72px) 0 clamp(28px, 3vw, 40px); }
.cs-head h1 { max-width: none; font-size: clamp(36px, 4.4vw, 60px); }
.cs-head .lead .tag { vertical-align: 2px; }
.cs-tabs {
  display: flex; width: fit-content; max-width: 100%; gap: 4px; margin-top: clamp(24px, 3vw, 36px); padding: 4px;
  overflow-x: auto; scrollbar-width: none; border-radius: 999px; background: var(--wash); box-shadow: inset 0 0 0 1px var(--line);
}
.cs-tabs::-webkit-scrollbar { display: none; }
.cs-tabs .nav-link { flex: none; gap: 8px; min-height: 40px; padding: 0 16px; font-size: 14.5px; white-space: nowrap; }
.cs-tabs .nav-link[aria-current="page"] { color: var(--ink); background: rgba(237, 238, 245, .08); box-shadow: inset 0 0 0 1px var(--line-2); }
.cs-tabs .nav-link[aria-current="page"]::before { content: ""; width: 6px; height: 6px; border-radius: 2px; background: var(--accent); }

.cs-body { display: flex; flex-direction: column; gap: clamp(20px, 2.4vw, 28px); padding-bottom: clamp(72px, 9vw, 128px); }
.cs-sec { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.cs-sec-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 6px 20px; }
.cs-h2 { margin: 0; font-size: clamp(20px, 1.8vw, 24px); line-height: 1.2; font-weight: 680; letter-spacing: -.02em; }
/* .cs-main in front: site.css sets every `.card p` to the body size, and these
   sit in cards. */
.cs-main .cs-meta { margin: 0; font-family: var(--mono); font-size: 12px; color: var(--dim); }
.cs-main .cs-note { margin: 0; font-size: 14.5px; color: var(--muted); text-wrap: pretty; }
.cs-main .card .lbl { margin: 0; font-size: 12px; color: var(--dim); }
.cs-main .card .kicker { font-size: 12.5px; line-height: 1.3; color: var(--muted); }
/* Console panels are denser than the storefront's tiles: a tighter radius. */
.cs-main .card, .cs-main .table-wrap { border-radius: 16px; }
.cs-main .card { gap: 14px; }

/* ── Alerts: flashes, errors, the verify banner ──────────────────────────── */
/* The ok tone is the changelog's call-out (.cl-do); a note is violet, the
   second accent, which never marks an action; a problem takes --danger. */
.cs-alert {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin: 0; padding: 14px 16px;
  border-radius: 14px; font-size: 15px; line-height: 1.5; color: var(--ink-2);
  background: var(--wash); box-shadow: inset 0 0 0 1px var(--line-2);
}
.cs-alert-text { flex: 1 1 240px; margin: 0; min-width: 0; text-wrap: pretty; }
.cs-alert form { margin: 0; }
.cs-alert.is-ok { background: color-mix(in oklch, var(--accent) 6%, transparent); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--accent) 26%, transparent); }
.cs-alert.is-note { background: color-mix(in oklch, var(--lilac) 8%, transparent); box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--lilac) 30%, transparent); }
.cs-alert.is-err { background: color-mix(in srgb, var(--danger) 7%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 36%, transparent); }
.cs-alert .pill { flex: none; }
.pill-note { color: var(--lilac); font-weight: 500; box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--lilac) 45%, transparent); }
.cs-alerts { display: flex; flex-direction: column; gap: 10px; }

/* ── Sign in, sign up, forgot, reset ─────────────────────────────────────── */
/* The page head's violet light behind one centred card. */
.page-head.cs-auth { padding: clamp(40px, 6vw, 96px) 0 clamp(72px, 9vw, 128px); }
.cs-auth-grid { display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start; gap: 28px clamp(32px, 5vw, 64px); }
.cs-auth-col { flex: 0 1 440px; min-width: 0; display: flex; flex-direction: column; gap: 14px; }
.card.cs-auth-card { gap: 0; padding: clamp(24px, 3vw, 36px); border-radius: 20px; box-shadow: inset 0 0 0 1px var(--line-2), 0 40px 90px -40px rgba(0, 0, 0, .9); }
.cs-auth-card .kicker { margin-bottom: 18px; }
.cs-auth-card h1 { max-width: none; margin: 0 0 10px; font-size: clamp(30px, 3.2vw, 40px); line-height: 1.02; }
.card .cs-sub { margin: 0; font-size: 15.5px; color: var(--muted); }
.cs-form { display: flex; flex-direction: column; gap: 16px; margin-top: 26px; }
.cs-form .btn-block { margin-top: 6px; }
.cs-hint { margin-left: 6px; font-family: var(--sans); font-size: 12.5px; letter-spacing: 0; text-transform: none; color: var(--dim); }
.input[aria-invalid="true"] { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 80%, transparent); }
/* nocturne.css draws the focus ring with box-shadow too, and the rule above,
   loaded later, replaced it: the field that needed fixing showed no focus at
   all, though the page puts the cursor there. Focused, it gets the design's
   ring in the error's colour, so it reads as both. */
.input[aria-invalid="true"]:focus-visible { box-shadow: inset 0 0 0 1px var(--danger), 0 0 0 4px color-mix(in srgb, var(--danger) 22%, transparent); }
.card .cs-alt { margin: 22px 0 0; padding-top: 18px; box-shadow: inset 0 1px 0 var(--line); font-size: 14.5px; color: var(--muted); }
.cs-alt a + a { margin-left: 14px; }
/* What the free key (or the plan) gives, beside the sign-up card. Wide
   screens only: on a phone it would push the form below the fold. */
.cs-aside { flex: 0 1 340px; min-width: 0; padding-top: clamp(24px, 3vw, 36px); display: flex; flex-direction: column; gap: 18px; }
.cs-aside .kicker { margin: 0; }
.cs-aside .h3 { margin: 0; font-size: 22px; line-height: 1.2; font-weight: 680; letter-spacing: -.02em; }
.cs-aside .checks { font-size: 13.5px; gap: 12px; }
.cs-aside .checks li { align-items: flex-start; }
.cs-aside .checks svg { margin-top: 2px; }
.cs-price { display: flex; align-items: baseline; gap: 10px; }
.cs-price .amount { font-size: 44px; }
.cs-price .price-period { margin: 0; }
@media (max-width: 900px) { .cs-aside { display: none; } }

/* ── Overview: figures and the 30-day chart ──────────────────────────────── */
.cs-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
/* Every figure at the same height: each sits a fixed step under its label,
   and whatever follows it (the Today meter and its line, or a single line)
   goes to the card's foot. Spread with space-between, the card with the
   meter had one more item to share the space with, and its figure sat
   higher than the other three. */
.cs-stat { justify-content: flex-start; min-height: 168px; }
.cs-main .cs-stat .cs-stat-v { margin-top: 8px; }
.cs-main .cs-stat .cs-stat-v + * { margin-top: auto; }
.cs-main .cs-stat-v {
  display: block; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: clamp(30px, 3vw, 42px); line-height: 1; font-weight: 650; font-stretch: 106%; letter-spacing: -.035em;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.cs-cap { text-transform: capitalize; }
.cs-main .cs-stat-m { margin: 0; font-family: var(--mono); font-size: 12px; color: var(--muted); }
.cs-stat-m a { color: var(--ink); }
.cs-stat .meter { margin-top: 0; }
@media (max-width: 960px) { .cs-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } .cs-stat { min-height: 148px; } }
/* Two figures a row on a phone: the plan's name ("Developer") has to fit
   in half the width, so the figures and the card's padding step down. */
@media (max-width: 520px) {
  .cs-stats { gap: 12px; }
  .cs-main .card.cs-stat { padding: 18px; }
  .cs-main .cs-stat-v { font-size: 28px; }
  .cs-main .cs-stat-v.cs-cap { font-size: 22px; line-height: 1.27; }
}
@media (max-width: 359px) { .cs-stats { grid-template-columns: minmax(0, 1fr); } }

.cs-bars {
  display: flex; align-items: flex-end; gap: 3px; height: 180px; padding-bottom: 1px;
  box-shadow: inset 0 -1px 0 var(--line-2);
}
.cs-bars span {
  flex: 1; min-width: 0; height: var(--h, 2%); min-height: 2px; border-radius: 4px 4px 0 0;
  background: var(--line-2); transition: background-color .25s;
}
/* The days are the ink's line steps and only the peak is lime: the design
   keeps lime for the one thing to look at. Lime thinned over the dark card
   mixed to olive, a colour the design does not have. */
.cs-bars span:hover { background: var(--line-3); }
.cs-bars span.is-peak { background: var(--accent); box-shadow: 0 0 18px -4px var(--accent); }
.cs-main .cs-axis { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 16px; margin: 0; font-family: var(--mono); font-size: 11.5px; color: var(--dim); }
@media (max-width: 520px) { .cs-bars { gap: 2px; height: 140px; } }
.cs-empty { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; }
.cs-empty p { flex: 1 1 280px; }
.cs-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0; }

/* ── API keys ────────────────────────────────────────────────────────────── */
/* The one time a key is shown: the featured plan card's lime edge, the key in
   the code windows' panel, and selected whole by one click (no script to
   copy it with). */
.card.cs-reveal {
  background: linear-gradient(180deg, #1A1D33 0%, #12142A 100%);
  box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--accent) 40%, transparent), 0 40px 90px -40px color-mix(in oklch, var(--accent) 40%, transparent);
}
.cs-key {
  display: block; margin: 0; padding: 14px 16px; border-radius: 12px; overflow-wrap: anywhere; word-break: break-all;
  font-family: var(--mono); font-size: 14.5px; line-height: 1.5; color: var(--ink);
  background: var(--panel); box-shadow: inset 0 0 0 1px var(--line-2);
  -webkit-user-select: all; user-select: all; cursor: text;
}
.cs-create { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) auto; align-items: end; gap: 16px; margin: 0; }
.cs-create .btn { min-height: 44px; }
@media (max-width: 720px) { .cs-create { grid-template-columns: minmax(0, 1fr); } }
.cs-keys .mono { font-size: 13px; color: var(--ink); white-space: nowrap; }
.cs-keys td { vertical-align: middle; }
.cs-keys td.cs-act { text-align: right; white-space: nowrap; }
/* One row height for every key. A working key's cell holds a 44px Revoke
   button (site.css .btn-sm) and a revoked key's only a small tag, so the
   rows alternated between two heights. A cell's height is its row's
   minimum, so this holds each row to the button's: 44px and the cell's
   14px above and below (site.css .table td; border-box, so the padding is
   inside the height). The phone layout below has its own heights. */
@media (min-width: 721px) { .cs-keys td.cs-act { height: calc(44px + 28px); } }
.cs-keys form { margin: 0; display: inline-flex; }
.cs-keys tr.is-revoked td { color: var(--dim); }
.cs-keys tr.is-revoked .mono { color: var(--dim); text-decoration: line-through; text-decoration-color: var(--line-3); }
.cs-revoke:hover { color: var(--danger); background: color-mix(in srgb, var(--danger) 8%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 50%, transparent); }
/* A phone gets one key per block: the name and its button on top, then the
   key and its dates, each labelled from its column's heading. */
@media (max-width: 720px) {
  .cs-keys thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .cs-keys, .cs-keys tbody { display: block; }
  .cs-keys tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 16px; padding: 16px; }
  .cs-keys td, .table.cs-keys td { grid-column: 1; padding: 0; }
  .cs-keys td.cs-act { grid-column: 2; grid-row: 1 / span 4; align-self: center; }
  .cs-keys td[data-label]::before { content: attr(data-label) "  "; font-family: var(--mono); font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--dim); }
  .cs-keys td.cs-name { font-weight: 600; color: var(--ink); }
  /* A revoked key is history: its name and key are enough. Without its
     dates it is half the height, so a long rotation history stays short. */
  .cs-keys tr.is-revoked { padding-block: 12px; }
  .cs-keys tr.is-revoked td[data-label] { display: none; }
  .cs-keys tr.is-revoked td.cs-act { grid-row: 1 / span 2; }
  .cs-keys tr.is-revoked td.cs-name { font-weight: 500; color: var(--dim); }
}

/* ── Billing ─────────────────────────────────────────────────────────────── */
.cs-main .prices { margin-top: 0; }
/* The plan meters stand filled. site.css grows them as the plans scroll in,
   which suits a page read top to bottom; here the plans sit at the fold,
   and until the page was scrolled a little every meter stood empty, as if
   the plan allowed nothing. */
.cs-main .prices .mfill { animation: none; }
.cs-main .price { flex-basis: 260px; }
.price-current { flex: none; }
.cs-plan-foot { display: flex; flex-direction: column; gap: 10px; }
.cs-plan-foot form { margin: 0; }
.cs-main .cs-plan-foot .cs-note { font-family: var(--mono); font-size: 12px; }
/* The foot of a card with nothing to press (the current plan, the free one):
   a button's size and shape, so every foot lines up, but plainly not a
   button: no fill, no hover, no press. */
.btn.cs-plan-here, .btn.cs-plan-here:hover { cursor: default; color: var(--muted); background: none; box-shadow: inset 0 0 0 1px var(--line); }
.btn.cs-plan-here:active { transform: none; }
.btn.cs-plan-here.is-current { color: var(--ink); box-shadow: inset 0 0 0 1px var(--line-2); }
.btn.cs-plan-here.is-current::before { content: ""; width: 6px; height: 6px; border-radius: 2px; background: var(--accent); }
.cs-sub-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px 32px; }
.cs-main .cs-sub-row .cs-note { flex: 1 1 360px; font-size: 15.5px; color: var(--ink-2); }
.cs-sub-row form { margin: 0; }
.cs-sub-row .tag { margin-right: 8px; }
.table td.cs-cap { text-transform: capitalize; }

@media (forced-colors: active) {
  .cs-alert, .cs-tabs, .cs-key { border: 1px solid CanvasText; }
}
