/* MinLine brand stylesheet -- the marketing, legal and account pages.
 *
 * ONE sheet for every surface OUTSIDE the app: /help, /terms, /privacy, and
 * every page auth.py and billing.py render (login, signup, forgot, reset,
 * billing, cancel). They carried five near-identical copies of these rules
 * until 2026-08-14 -- terms and privacy were byte-for-byte the same but for
 * two blocks, and the auth pages restated the whole thing inside a Python
 * f-string, where every literal brace has to be doubled.
 *
 * NOT the app. `index.html` has its own system (two themes, system-ui, dense
 * 11-13px tables); see DESIGN_SYSTEM.md. NOT landing.html either, which runs
 * a third palette -- that is an open decision, not an oversight.
 *
 * THE TOKENS AGREE WITH THE APP'S LIGHT THEME WHERE THEY OVERLAP: --accent,
 * --good and --bad are the app's light values exactly, so a blue link or a
 * red error is the same blue and the same red in both places. Navy is the
 * brand chrome and has no counterpart in the app.
 *
 * Served through `_page` in main.py, so it revalidates and costs a 304 --
 * StaticFiles would apply heuristic freshness and a restyle could sit
 * invisible in a browser cache. It is in BOTH gates' public lists: the login
 * page needs it and there is no session yet.
 */

:root {
  --navy:       #16233F;   /* brand chrome: wordmark, headings, primary fill */
  /* THE NEUTRALS ARE THE APP'S LIGHT THEME, NOT A SECOND SET (2026-08-14,
     Wil: "the coloring on the login page doesn't match the rest of the
     website"). They were close-but-different -- ground #F8F9FA against the
     app's #eef1f5, ink #111827 against #1a2029, dim #6B7280 against #64748b,
     rules #E5E7EB against #d7dee6 -- which is the worst kind of mismatch,
     near enough to look like a mistake rather than a decision. Navy stays,
     because it is the BRAND (wordmark, favicon, manifest theme), and the app
     has no counterpart for it. */
  --ink:        #1a2029;   /* body ink -- the app's --text */
  --prose:      #374151;   /* long-form paragraphs, a step lighter than ink */
  --dim:        #64748b;   /* captions, labels, secondary links */
  --line:       #d7dee6;   /* borders and rules */
  --field-line: #d7dee6;   /* fields share the rule colour, as in the app */
  --bg:         #eef1f5;   /* page ground */
  --panel:      #ffffff;   /* cards and the nav bar */
  --accent:     #2563EB;   /* interactive -- matches the app's light accent */
  --good:       #15803d;
  --bad:        #dc2626;
  --measure:     860px;    /* prose column; the help form overrides to 640 */
  --r-field:     8px;
  --r-card:     12px;
}

* { box-sizing: border-box; margin: 0; }

/* **THE APP'S FACE, NOT A WEB FONT** (2026-08-27). These pages pulled Inter
   from Google Fonts, which put a BLOCKING THIRD-PARTY REQUEST on the sign-in
   path -- the page a returning pilot on hotel wifi is most likely to hit, and
   one the offline work exists to keep usable. It was also the last thing
   making them read as a different family from the app, now that their
   neutrals are the app's.
   `landing.html` KEEPS Inter and its own scheme: that page is deliberately its
   own identity (see the register in DESIGN_SYSTEM.md), and it is the one page
   a visitor sees once rather than works in. */
body { background: var(--bg); color: var(--ink); line-height: 1.6;
       font-family: system-ui, -apple-system, "Segoe UI", Arial, sans-serif; }

/* The account pages are a single centred card UNDER THE STANDARD MASTHEAD
   (Wil, 2026-08-14). The bar is the site's, so signing in reads as part of
   MinLine rather than a bare form on a grey field. A COLUMN, not a centred
   flex box: with the bar as a flex child of a centring body it would have sat
   BESIDE the card. The card centres in what is left below the bar, so it stays
   optically centred whatever the window height. */
body.centered { display: flex; flex-direction: column; min-height: 100vh; }
body.centered main { flex: 1 1 auto; display: flex; align-items: center;
                     justify-content: center; max-width: none;
                     padding: 24px; margin: 0; }

/* ---- masthead ----------------------------------------------------------
 * **THE SAME BAR AS THE APP'S HEADER** (2026-08-14, Wil: help "carries a
 * slightly different logo and top line ... make it match the rest of the
 * website"). It was a 34px mark with a 20px/800 wordmark on a 64px bar --
 * landing-page scale -- against the app's 22px mark, 16px/700 wordmark and
 * 57px header. Now 56px + the 1px border = 57, and the mark and wordmark are
 * the app's to the pixel, so moving between /app and /help does not restate
 * the brand at two sizes.
 * **THE BAR IS FULL-BLEED, LIKE THE APP'S HEADER** (Wil, 2026-08-14: align it
 * "the same on those as everywhere else", and put the right-hand link "to the
 * far right where the account icon is"). It was a centred 860px column, so on
 * a 1280px window it sat inset 234px each side while the app's header ran edge
 * to edge -- the logo landed at x=234 against the app's 20, and the right-hand
 * link stopped 234px short of the window. Now `padding: 0 20px`, the header's
 * own inset, so the wordmark is hard left and the link is hard right on every
 * page.
 * **The CONTENT column below is still per-page** (`--measure`), which is the
 * normal arrangement: a site-wide bar over a centred column. It is also why
 * the bar must never take the page's measure -- doing that put help's logo
 * ~110px right of where it sat on /terms. */
nav { background: var(--panel); border-bottom: 1px solid var(--line); }
/* **THE WORDMARK STARTS AT 80px, WHERE IT STARTS IN THE APP** (Wil,
   2026-08-14: keep the logo's location consistent "even [on] those without the
   hamburger icon"). In the app the nav toggle sits at the header's 20px inset
   and is 44px wide, and the header's gap is 16 -- so the wordmark begins at
   20 + 44 + 16 = 80. These pages have no toggle, so without the inset their
   wordmark started at 20 and shifted 60px left of the app's every time you
   left the product. The RIGHT edge keeps the plain 20px, so the link still
   lines up with the app's account icon.
   **IT IS DERIVED, NOT DECORATIVE**: change the toggle's size or the header's
   gap and this has to move with it, or the two drift apart again. */
.nav-inner { max-width: none; margin: 0; padding: 0 20px 0 80px;
             height: 56px; display: flex; align-items: center;
             justify-content: space-between; }
.brand { display: flex; align-items: center; gap: 8px; font-weight: 700;
         font-size: 16px; letter-spacing: .04em; color: var(--navy);
         text-decoration: none; }
.brand svg { width: 22px; height: 22px; }
.nav-inner a.plain { color: var(--dim); text-decoration: none;
                     font-size: 14.5px; font-weight: 600; }

main { max-width: var(--measure); margin: 0 auto; padding: 40px 24px 80px; }

/* ---- prose ------------------------------------------------------------- */
h1 { font-size: 32px; font-weight: 800; letter-spacing: -1px; color: var(--navy); }
h2 { font-size: 19px; font-weight: 700; color: var(--navy); margin: 30px 0 8px; }
p, li { font-size: 15px; color: var(--prose); }
p { margin-bottom: 12px; }
ul { margin: 0 0 12px 22px; }
li { margin-bottom: 6px; }
.meta, p.sub { color: var(--dim); font-size: 14.5px; margin: 6px 0 26px; }

footer { border-top: 1px solid var(--line); color: var(--dim); font-size: 13px;
         max-width: var(--measure); margin: 0 auto; padding: 24px; }
footer a { color: var(--dim); }

table { border-collapse: collapse; width: 100%; font-size: 14px;
        margin-bottom: 14px; }
th, td { border: 1px solid var(--line); padding: 8px 10px; text-align: left;
         vertical-align: top; color: var(--prose); }
th { background: var(--panel); color: var(--navy); }

/* Callouts. `.draft` flags an unreviewed legal document, `.ph` marks a
   placeholder inside one, `.hl` lifts a paragraph worth not missing. */
.draft { background: #FFFBEB; border: 1px solid #FDE68A; color: #92400E;
         border-radius: 10px; padding: 12px 16px; font-size: 14px;
         margin-bottom: 28px; }
.ph { background: #FEF3C7; border-radius: 4px; padding: 0 4px; }
.hl { background: #EFF6FF; border: 1px solid #BFDBFE; border-radius: 10px;
      padding: 14px 16px; margin: 8px 0 16px; }
.caps { text-transform: none; }

/* ---- surfaces ---------------------------------------------------------- */
.card { background: var(--panel); border: 1px solid var(--line);
        border-radius: var(--r-card); padding: 28px 30px;
        box-shadow: 0 10px 30px rgba(22,35,63,.06); }
/* The account card is narrower, tighter and floats on its own. */
.card.auth { padding: 34px 38px; width: 400px; max-width: 92vw;
             box-shadow: 0 12px 30px rgba(22,35,63,.08); }
.card.auth h1 { font-size: 19px; margin: 0 0 4px; }
.card.auth p.sub { font-size: 13.5px; margin: 0 0 20px; }

/* ---- forms ------------------------------------------------------------- */
label { display: block; font-size: 13px; font-weight: 700; color: var(--navy);
        margin: 18px 0 6px; }
/* The first label needs no top margin -- the card's own padding is the space
   above it, and 18px on top of that reads as a gap nobody chose. */
form > label:first-child, .card > form > label:first-child { margin-top: 0; }
/* The account forms label in small caps, which reads as a form rather than a
   document and keeps a 400px card legible. */
.card.auth label:not(.check) { font-size: 12px; color: var(--dim);
                   text-transform: uppercase; letter-spacing: 1px;
                   margin: 14px 0 5px; }
.opt { color: var(--dim); font-weight: 500; }

/* A TICK BOX AND ITS SENTENCE, side by side.
 *
 * Everything in this section is written for TEXT FIELDS, and a checkbox is not
 * one. The exclusions that carry that -- here, on the input rule below, and in
 * the coarse-pointer block -- are load-bearing in exactly the way
 * `:not(.pw-toggle)` is on the button rules, and for the same reason: a rule
 * aimed at "the fields in this card" catches every control shaped like one.
 *
 * What shipped without them, on staging 2026-08-31: the billing page's "Add
 * Waypoint" tick took `width: 100%`, filled the whole flex row, shoved its own
 * sentence past the right edge of the card into a column one word wide -- and
 * `.card.auth label` set that sentence in dim uppercase, so a paragraph wore a
 * field label's clothes. Three separate rules, one control none of them meant.
 *
 * The label wraps the text deliberately: the sentence is then part of the hit
 * target, which is what makes this usable on the iPad without a 44px tick. */
label.check { display: flex; align-items: flex-start; gap: 9px;
              margin: 0 0 14px; font-size: 14px; font-weight: 500;
              line-height: 1.45; color: var(--ink); cursor: pointer;
              text-transform: none; letter-spacing: normal; }
label.check input[type="checkbox"] { flex: none; width: 18px; height: 18px;
              min-height: 0; margin: 1px 0 0; padding: 0;
              accent-color: var(--accent); }

input:not([type="checkbox"]), textarea {
                  width: 100%; border: 1px solid var(--field-line);
                  border-radius: var(--r-field); padding: 11px 13px;
                  font-size: 15px; font-family: inherit;
                  background: var(--panel); color: var(--ink); }
.card.auth input:not([type="checkbox"]) { padding: 10px 12px; }
textarea { min-height: 150px; resize: vertical; }
/* The checkbox is excluded from `outline: none` as well, and this one is an
   ACCESSIBILITY bug rather than a cosmetic one: a text field replaces the ring
   with a blue border, so dropping the outline still leaves focus visible. A
   tick box has no border to change, so the same rule would make it focusable
   by keyboard and impossible to see. It keeps the platform ring. */
input:not([type="checkbox"]):focus, textarea:focus {
                  outline: none; border-color: var(--accent); }

/* **ONE TREATMENT, THE SAME ONE THE APP USES** (Wil, 2026-08-14): grey
   outline at rest, blue on hover, and only when the button is available. It
   replaced a solid navy fill, which was the loudest thing on the login page
   and most of why that page read as a different site. Weight and padding are
   what mark the main action now, not colour. */
button { margin-top: 24px; background: transparent; color: var(--dim);
         border: 1px solid var(--line);
         border-radius: var(--r-field); padding: 13px 26px; font-weight: 700;
         font-size: 15px; cursor: pointer; font-family: inherit; }
button:not(.pw-toggle):hover:not(:disabled) { color: var(--ink); border-color: var(--accent); }
button:disabled { opacity: .5; cursor: default; }
/* **`:not(.pw-toggle)` IS LOAD-BEARING, NOT TIDINESS.** The show/hide eye is a
   <button> INSIDE this card, and `.card.auth button` (0-2-1) out-ranks
   `.pw-toggle` (0-1-0) -- so without the exclusion the eye takes `width: 100%`
   and spans the whole field, putting the icon in the middle of it. That is
   exactly what shipped on 2026-08-14: the old rule in auth.py was a bare
   `button` (0-0-1), which the class beat, and scoping it here silently
   inverted the winner. Any new rule aimed at "the buttons in this card" needs
   the same exclusion. */
.card.auth button:not(.pw-toggle) { width: 100%; margin-top: 20px; padding: 11px; }

/* There is no secondary variant any more: one treatment covers every button,
   so billing's outlined buttons are plain <button> again. They had drifted to
   a 2px border as an inline style, which is what the class was introduced to
   stop; the shared rule stops it by construction. */

/* ---- feedback ---------------------------------------------------------- */
.msg { margin-top: 18px; font-size: 14.5px; font-weight: 600; min-height: 1.4em; }
.msg.ok  { color: var(--good); }
.msg.err { color: var(--bad); }
/* Banners above a form, where the message needs a surface of its own. */
.err { background: #FEF2F2; color: #B91C1C; border: 1px solid #FECACA;
       border-radius: var(--r-field); padding: 9px 12px; font-size: 13.5px;
       margin-bottom: 6px; }
.ok  { background: #F0FDF4; color: #166534; border: 1px solid #BBF7D0;
       border-radius: var(--r-field); padding: 9px 12px; font-size: 13.5px;
       margin-bottom: 6px; }
.links { margin-top: 16px; font-size: 13.5px; color: var(--dim);
         text-align: center; }
.links a { color: var(--accent); text-decoration: none; font-weight: 600; }

.done { text-align: center; padding: 26px 10px; }
.done h2 { color: var(--navy); font-size: 22px; margin-top: 0; }
.done p { color: var(--dim); font-size: 15px; margin-top: 8px; }

/* ---- show/hide password ------------------------------------------------
 * Applied by script to every input[type=password], so a new password field
 * anywhere gets the toggle with no markup. The button MUST be type="button":
 * a bare <button> in a form defaults to submit, so the eye would post the
 * login form instead of revealing the password. */
.pw-wrap { position: relative; display: block; }
.pw-wrap input { padding-right: 44px; }
.pw-toggle { position: absolute; right: 1px; top: 1px; bottom: 1px; width: 40px;
             margin: 0; padding: 0; background: transparent; border: 0;
             border-radius: 0 var(--r-field) var(--r-field) 0; color: var(--dim);
             cursor: pointer; display: flex; align-items: center;
             justify-content: center; }
.pw-toggle:hover { background: #F3F4F6; color: var(--navy); }
.pw-toggle svg { width: 19px; height: 19px; display: block; }

/* Touch: same rule as the app -- a coarse pointer, not a narrow window,
 * because a tablet in landscape is wide AND touched. */
@media (pointer: coarse) {
  /* textarea is EXCLUDED: it already stands 150px, and a 44px floor
     here would out-rank that base rule on any touch device and
     collapse the help form's message box. A checkbox is excluded too --
     44px of tick box is not a bigger target, it is a stretched control;
     `label.check` puts the sentence in the hit area instead. */
  button, input:not([type="checkbox"]), select { min-height: 44px; }
}

/* Billing's two note shapes, which were inline styles repeated per page. */
.note { color: var(--dim); font-size: 12.5px; margin-top: 12px; }
.lead { font-size: 14px; color: var(--prose); margin-bottom: 14px; }

/* THE THREE DOORS on minline.bid's front page (`auth.gateway_page`, added
 * 2026-09-01 when `/` stopped redirecting to PocketFE).
 *
 * Each is a whole-block link rather than a heading with a button beside it:
 * one destination should have one target, and a card with a small button in it
 * leaves a dead margin that reads as clickable and is not.
 *
 * ONE accent border, on Sign in, and the rest are plain. Three equally loud
 * options is the same as none — the pilot who has an account is the commonest
 * arrival here, because this address is a bookmark. The other two are not
 * quieter in SIZE, only in outline: "try the demo" is a real door and must not
 * look like a footnote.
 *
 * The `b`/`span` pair is a label and its consequence, which is the shape every
 * other list of choices in this app uses. */
.gateway { display: grid; gap: 10px; margin: 4px 0 20px; }
.gw {
  border: 1px solid var(--line); border-radius: var(--r-card);
  color: var(--ink); display: block; padding: 13px 15px;
  text-decoration: none; transition: border-color .12s, background .12s;
}
.gw:hover, .gw:focus-visible { background: var(--panel); border-color: var(--accent); }
.gw.primary { border-color: var(--accent); }
.gw b { display: block; font-size: 14.5px; font-weight: 600; }
.gw span { color: var(--dim); display: block; font-size: 12.5px; margin-top: 2px; }
