/* =====================================================================
   GOYO SHARED BRAND SYSTEM - tokens and primitives
   goyo-brand.css   v20260913a

   ONE source of truth for color, type, spacing and the shared primitives
   (BrandLockup, AppHeader, Button, FormField, Card, Status, Footer).
   Changing a token here changes every consuming page. Pages must not
   redefine these values locally.

   SCOPE AND SUPERSESSION
   Everything the shell owns is scoped under .gshell / .gpage. That scope
   is deliberate: it outranks the two legacy header rule sets (goyo.css
   base .top block and its later overlay) and the geometry goyo-gate.js
   injects at runtime, without editing either file. See INTEGRATION.md
   for the exact list of rules this supersedes.

   Load order on a page:  goyo.css  ->  goyo-brand.css  ->  goyo-gate.js
   ===================================================================== */

/* ---------------------------------------------------------------- tokens */
:root{
  /* brand ---------------------------------------------------------- */
  --g-navy:#35506B;          /* primary: buttons, links, focus      8.363:1 on white */
  --g-navy-h:#243A50;        /* hover/active */
  --g-navy-deep:#1E3650;     /* limited hero / brand surfaces      12.362:1 on white */
  --g-navy-bg:#E8EEF4;       /* tinted surface */
  --g-gold:#8A6A1E;          /* small text on light                 5.047:1 on white */
  --g-gold-halo:#E8C46A;     /* DECORATION ONLY - 1.675:1 on white. Never functional text. */

  /* ink and surface ------------------------------------------------ */
  --g-ink:#121A24;           /* body                               17.515:1 on white */
  --g-ink-2:#4E5966;         /* secondary                           7.131:1 on white */
  --g-bg:#FFFFFF;
  --g-bg-2:#F5F6F4;
  --g-line:#CBD1CD;
  --g-line-2:#E4E8E5;
  --g-card:#FFFFFF;

  /* status - always paired with text, never colour alone ----------- */
  --g-ok:#1B6B4A;  --g-ok-bg:#EAF3EE;
  --g-warn:#8A6A1E; --g-warn-bg:#FAF4E4;
  --g-stop:#8C2F1F; --g-stop-bg:#FBEDEA;

  /* type ----------------------------------------------------------- */
  --g-serif:Literata,Georgia,"Times New Roman",serif;
  --g-sans:"Atkinson Hyperlegible Next",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  --g-mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  --g-body:18px;      --g-body-lh:1.55;
  --g-small:16px;     --g-label:14px;
  --g-h1:40px;        --g-h1-lh:44px;
  --g-h2:26px;        --g-h2-lh:32px;
  --g-h3:20px;        --g-h3-lh:26px;
  --g-hero:48px;      --g-hero-lh:53px;

  /* lockup --------------------------------------------------------- */
  --g-mark:40px;             /* mark, desktop */
  --g-wordmark:24px;         /* wordmark, desktop */
  --g-lockup-gap:10px;

  /* shell ---------------------------------------------------------- */
  --g-header-h:72px;         /* desktop, at normal text size */
  --g-container:1200px;
  --g-gutter:24px;

  /* measures ------------------------------------------------------- */
  --g-measure-read:65ch;
  --g-measure-form:960px;
  --g-measure-work:1200px;

  /* spacing scale -------------------------------------------------- */
  --g-1:4px; --g-2:8px; --g-3:12px; --g-4:16px; --g-6:24px; --g-8:32px; --g-12:48px; --g-16:64px;

  /* controls ------------------------------------------------------- */
  --g-control:48px;          /* main controls */
  --g-control-compact:44px;  /* compact target (Goyo preference, not a WCAG claim) */
  --g-radius:4px;
  --g-radius-lg:8px;
  --g-focus:3px;
}

/* Page-level sizes follow the VIEWPORT. The header's own sizes do not:
   they follow the container it is given (see .gshell-w below), so a header
   in a narrow panel on a wide screen is still correct - and a wide header
   in a narrow preview is not wrongly shrunk. */
@media (max-width:640px){
  :root{
    /* standalone lockups only; the header overrides these on .gshell-w */
    --g-mark:32px; --g-wordmark:22px;
    --g-gutter:16px;
    --g-h1:32px; --g-h1-lh:36px;
    --g-h2:23px; --g-h2-lh:29px;
    --g-hero:36px; --g-hero-lh:41px;
  }
}

/* dark is a STATE of the same system: the same tokens, re-pointed. */
html[data-theme=dark]{
  --g-navy:#9BB8D6;          /* link/primary on dark               8.64:1 on #17181B */
  --g-navy-h:#B6CDE6;
  --g-navy-deep:#101B29;
  --g-navy-bg:#1F2A36;
  --g-gold:#D6B76C;
  --g-ink:#ECEDEE;           /*                                   15.145:1 on #17181B */
  --g-ink-2:#B4B7BC;
  --g-bg:#17181B;
  --g-bg-2:#1F2125;
  --g-line:#3A3E45;
  --g-line-2:#2A2D32;
  --g-card:#1F2125;
  --g-ok:#66C299;  --g-ok-bg:#17281F;
  --g-warn:#D6B76C; --g-warn-bg:#2A2317;
  --g-stop:#E9998A; --g-stop-bg:#2E1B17;
}

/* --------------------------------------------------------------- surface
   Dark is a state of the same system, so the surface belongs to the system.
   Without this the re-pointed dark ink lands on a white page: measured
   2.01:1 before this rule existed. */
html{background:var(--g-bg); color-scheme:light}
html[data-theme=dark]{color-scheme:dark}
body{background:var(--g-bg); color:var(--g-ink)}

/* The element the header is mounted into is what sticks - see mountHeader().
   Sticking anything inside the shell cannot work: its parent is header-height, so the
   sticky box has zero travel. The host is a child of <body> and can travel the page.
   The background is explicit so page content never shows through the bar as it passes. */
.gshell-host{position:sticky; top:0; z-index:60; background:var(--g-bg)}
@media print{.gshell-host{position:static}}

/* Who the site is for, under the name in the footer. Quiet: it is a statement of fact, not a
   slogan, and it should read as part of the name rather than shout over it. */
.gfoot .brandwho{margin:2px 0 0; font-size:15.5px; color:var(--g-ink-2); letter-spacing:.01em}

/* ============================================================ AppHeader */
/* .top is intentionally NOT a direct child of <header>: goyo-gate.js moves
   `header > .top` into <body> for its own sticky, which would break this
   scope. One extra wrapper keeps the shell whole and sticky is ours. */
/* The header adapts to the width it is GIVEN, not to the window: the same
   object is then correct full-bleed, inside a narrower panel, and in a
   review stage, and the evidence is reproducible at any width. */
/* inline-size containment stops an element sizing to its content, so in any
   shrink-to-fit parent (flex row, inline-block, grid auto track, table cell)
   a bare .gshell collapsed to padding+border and its bar overflowed. The
   shell is a full-width block wherever it is used, so say so. */
.gshell{
  display:block; width:100%; box-sizing:border-box;
  /* 320px is the narrowest width this system is tested at, so it is also the
     floor that stops a zero-width shrink-to-fit parent collapsing the bar */
  min-width:320px;
  container-type:inline-size; container-name:gshell;
}
.gshell .gshell-w{
  --g-collapsed:0; --g-narrow:0;
  --g-header-h:72px; --g-mark:40px; --g-wordmark:24px; --g-gutter:24px;
  position:sticky; top:0; z-index:60; background:var(--g-bg); border-bottom:1px solid var(--g-line)}
.gshell .top{border:0; background:transparent}
.gshell .top .in{
  box-sizing:border-box; max-width:var(--g-container); margin:0 auto;
  padding:0 var(--g-gutter); min-height:var(--g-header-h);
  display:flex; align-items:center; gap:var(--g-3);
  flex-wrap:nowrap; position:relative;
}
/* the reserved-row hack the gate adds while the account is unresolved is
   not needed here: this shell reserves the slot itself, at full height. */
.gshell .top .in::after{content:none !important}

/* --- BrandLockup ------------------------------------------------------
   Self-contained: usable anywhere, not only inside the header. .gshell .logo
   is kept as an alias so the header and the authentication layer's own
   `.logo` hook are unaffected. */
.glockup,.gshell .logo{
  display:inline-flex; align-items:center; gap:var(--g-lockup-gap);
  flex:0 0 auto; text-decoration:none; color:var(--g-ink); padding:0; min-width:0;
  font-family:var(--g-sans);
}
.glockup svg,.gshell .logo svg{
  width:var(--g-mark); height:var(--g-mark); display:block; flex:0 0 auto;
}
.glockup b,.gshell .logo b{
  font-family:var(--g-serif); font-weight:700; font-size:var(--g-wordmark);
  line-height:1.15; letter-spacing:-.01em; white-space:nowrap;
}
.glockup b i,.gshell .logo b i{font-style:normal; color:var(--g-navy)}
/* A standalone lockup takes its size from :root, which follows the viewport.
   Nothing is declared on the lockup element itself: every lockup carries both
   .glockup and .logo, so an element-level declaration would also hit the one
   in the header and beat the container-query value it must inherit. The
   header is unaffected because .gshell-w declares these itself - a nearer
   ancestor than :root - in both its default and its container-query form. */
.glockup:focus-visible{outline:var(--g-focus) solid var(--g-navy); outline-offset:2px; border-radius:var(--g-radius)}

/* --- navigation ------------------------------------------------------- */
.gshell .gshell-panel{display:flex; align-items:center; min-width:0; flex:1 1 auto}
.gshell .gnav{
  display:flex; align-items:center; gap:2px; min-width:0; flex:1 1 auto;
  flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none; -ms-overflow-style:none;
}
.gshell .gnav::-webkit-scrollbar{display:none}
/* Held while the authentication answer is outstanding: the row keeps the
   width and height it is about to need, so the bar cannot move, and says
   nothing untrue in the meantime. */
.gshell .gnav[data-state=pending],.gshell .gshell-keep[data-state=pending]{visibility:hidden}
.gshell .gnav:empty{min-height:var(--g-control-compact)}
.gshell .gnav>a{
  flex:0 0 auto; display:inline-flex; align-items:center;
  min-height:var(--g-control-compact); padding:0 var(--g-3);
  border-radius:var(--g-radius); font:500 var(--g-small)/1.2 var(--g-sans);
  color:var(--g-ink-2); text-decoration:none; white-space:nowrap;
}
.gshell .gnav>a:hover{color:var(--g-ink); background:var(--g-bg-2)}
.gshell .gnav>a.on{color:var(--g-ink); font-weight:700; box-shadow:inset 0 -3px 0 var(--g-gold-halo)}
/* A route that must stay findable lives outside the scrolling row, so it
   can never be cut in half by it. */
.gshell .gshell-keep{display:flex; align-items:center; gap:var(--g-2); flex:0 0 auto}
.gshell .gshell-keep>a{
  display:inline-flex; align-items:center; min-height:var(--g-control-compact);
  padding:0 var(--g-3); border:1px solid var(--g-navy); border-radius:var(--g-radius);
  font:600 var(--g-small)/1.2 var(--g-sans); color:var(--g-navy);
  text-decoration:none; white-space:nowrap;
}
.gshell .gshell-keep>a:hover{background:var(--g-navy); color:#fff}
html[data-theme=dark] .gshell .gshell-keep>a:hover{color:#101B29}

/* --- account slot (filled by the authentication layer) ---------------- */
.gshell .goyo-acc{
  display:flex; align-items:center; justify-content:flex-end; gap:var(--g-2);
  /* never shrinks: a box narrower than its own contents does not clip them,
     it lets them paint outside itself - over the lockup, in this bar */
  flex:0 0 auto; min-height:var(--g-control-compact);
  font:500 var(--g-small)/1.25 var(--g-sans); color:var(--g-ink-2);
}
.gshell .goyo-acc .who{display:flex; align-items:center; gap:6px; min-width:0}
/* the slot is reserved at a readable width while it is empty, so the bar
   cannot change shape when the answer arrives */
.gshell .goyo-acc:empty{min-width:96px}
.gshell .goyo-acc .nm{font-weight:600; color:var(--g-ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:14ch}
.gshell .goyo-acc a,.gshell .goyo-acc button.out{
  display:inline-flex; align-items:center; min-height:var(--g-control-compact);
  padding:0 var(--g-2); font:500 var(--g-small)/1.25 var(--g-sans);
  color:var(--g-navy); background:none; border:0; border-radius:var(--g-radius);
  text-decoration:none; white-space:nowrap; cursor:pointer;
}
.gshell .goyo-acc button.out{color:var(--g-ink-2)}
.gshell .goyo-acc a:hover,.gshell .goyo-acc button.out:hover{background:var(--g-bg-2); color:var(--g-ink)}
.gshell .goyo-acc .tag{
  font:700 10.5px/1 var(--g-sans); letter-spacing:normal; text-transform:none;
  padding:4px 6px; border:1px solid var(--g-line); border-radius:var(--g-radius); color:var(--g-gold);
}
.gshell .goyo-acc .say{white-space:nowrap; color:var(--g-ink-2)}

/* --- theme + menu ----------------------------------------------------- */
.gshell .gshell-btn{
  flex:0 0 auto; display:inline-flex; align-items:center; gap:var(--g-2);
  min-height:var(--g-control-compact); padding:0 var(--g-3);
  font:600 var(--g-small)/1 var(--g-sans); color:var(--g-ink-2);
  background:var(--g-bg); border:1px solid var(--g-line); border-radius:var(--g-radius); cursor:pointer;
}
.gshell .gshell-btn:hover{color:var(--g-ink); border-color:var(--g-ink)}
.gshell .gshell-btn .ico{width:18px; height:18px; display:block; flex:0 0 auto}
.gshell .gshell-btn[data-icon-only=true]{min-width:var(--g-control-compact); padding:0 var(--g-2); justify-content:center}
.gshell .gshell-menu{display:none}
.gshell .gshell-menu .bars{display:block; width:18px; height:2px; background:currentColor; position:relative}
.gshell .gshell-menu .bars::before,.gshell .gshell-menu .bars::after{
  content:""; position:absolute; left:0; width:18px; height:2px; background:currentColor;
}
.gshell .gshell-menu .bars::before{top:-6px} .gshell .gshell-menu .bars::after{top:6px}

/* one visible focus treatment for everything in the shell */
.gshell a:focus-visible,.gshell button:focus-visible{
  outline:var(--g-focus) solid var(--g-navy); outline-offset:2px; border-radius:var(--g-radius);
}

/* The theme control is a glyph at every width. Showing the word only on wide
   screens made the bar's width depend on a second breakpoint - which is why
   1440 clipped worse than 1280. The accessible name still reads
   "Dark theme" / "Light theme". */
.gshell .gshell-theme .lbl{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}
.gshell .gshell-theme{min-width:var(--g-control-compact); padding:0 var(--g-2); justify-content:center}

/* One inline density, applied whenever the row is inline and never switched
   off by getting wider. */
.gshell[data-layout=inline] .top .in{column-gap:var(--g-2)}
/* Nothing in the inline row shrinks. GoyoBrand budgets the row before
   choosing this layout - counting the display name at its truncation cap -
   so every part gets exactly the width that budget assumed. Letting parts
   shrink afterwards was what pushed the name and then the account links out
   past their own box while the bar still claimed to fit. */
/* The panel is part of the bar, so the no-shrink rule applies to it too.
   Left flexible, it absorbed every pixel of shrink and the navigation
   inside it spilled over the Plans slot and the account strip while the
   bar itself still reported that everything fitted. */
.gshell[data-layout=inline] .gshell-panel,
.gshell[data-layout=inline] .gnav,
.gshell[data-layout=inline] .gshell-keep{flex:0 0 auto; min-width:0}
.gshell[data-layout=inline] .gshell-panel{flex:1 0 auto}
.gshell[data-layout=inline] .gnav{flex:1 0 auto}
/* The narrowest bars keep the control and drop the words around it: at 320
   "Example - read-only" and "Create your account" cannot both share a row
   with the lockup, and the control is the part that does something. */
.gshell .top .in>.goyo-acc[data-compact=true] .say,
.gshell .top .in>.goyo-acc[data-compact=true] .tag,
.gshell .top .in>.goyo-acc[data-compact=true] .who{display:none}
.gshell[data-layout=inline] .gnav>a,
.gshell[data-layout=inline] .gshell-keep>a{padding:0 var(--g-2)}
.gshell[data-layout=inline] .goyo-acc{gap:var(--g-1)}
.gshell[data-layout=inline] .goyo-acc a,
.gshell[data-layout=inline] .goyo-acc button.out{padding:0 6px}
/* A constant truncation. A name that snaps back to full length as the screen
   grows reclaims more width than the extra screen gave. */
.gshell .goyo-acc .nm{max-width:11ch}

/* --- collapse: measured, not guessed ---------------------------------
   GoyoBrand sets data-layout="menu" when the inline row does not actually
   fit its own content - whatever the container width, the label set or the
   length of the display name. A fixed breakpoint cannot know how wide
   "Access requests" plus a long name will be, and cut labels in every band
   where the guess and the content disagreed. */
@container gshell (max-width:640px){
  /* set on a descendant, not on .gshell: a container query never matches
     the container element itself. These inherit to the whole bar. */
  .gshell .gshell-w{--g-narrow:1; --g-header-h:64px; --g-mark:32px; --g-wordmark:22px; --g-gutter:16px}
}

.gshell[data-layout=menu] .gshell-menu{display:inline-flex}
.gshell[data-layout=menu] .gshell-panel{
  position:absolute; left:0; right:0; top:100%; z-index:5;
  display:none; padding:var(--g-2) var(--g-gutter) var(--g-4);
  background:var(--g-bg); border-bottom:1px solid var(--g-line);
  box-shadow:0 10px 24px rgba(18,26,36,.10);
}
.gshell[data-layout=menu] .gshell-panel[data-open=true]{display:block}
.gshell[data-layout=menu] .gnav{flex-direction:column; align-items:stretch; overflow:visible; gap:0}
.gshell[data-layout=menu] .gnav>a{min-height:var(--g-control); padding:0 var(--g-3); font-size:var(--g-body); border-radius:var(--g-radius)}
.gshell[data-layout=menu] .gnav>a.on{box-shadow:inset 3px 0 0 var(--g-gold-halo)}
.gshell[data-layout=menu] .gshell-panel>.gshell-keep{display:block; margin-top:var(--g-2)}
.gshell[data-layout=menu] .gshell-panel>.gshell-keep>a{width:100%; min-height:var(--g-control); justify-content:center}
.gshell[data-layout=menu] .goyo-acc{margin-left:auto}
/* A Menu with nothing behind it is worse than no Menu. This has to out-rank
   the rule above, which it ties with on specificity, so it is both more
   specific and later. */
.gshell[data-layout] .gshell-menu[data-empty=true]{display:none}

@container gshell (max-width:640px){
  /* the slot may shrink; at 320 the bar was 531px wide and the document
     scrolled sideways */
  .gshell .goyo-acc{gap:0}
  .gshell .top .in>.goyo-acc .say,.gshell .top .in>.goyo-acc .tag{
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; max-width:13ch;
  }
  /* on a narrow bar the Menu keeps its glyph and loses its written label;
     the accessible name is unchanged */
  .gshell .gshell-menu>span:not(.bars){position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}
  .gshell .gshell-menu{min-width:var(--g-control-compact); padding:0 var(--g-2); justify-content:center}
  /* account controls that do not fit the bar are placed in the Menu panel
     by GoyoBrand; there they are full size again */
  .gshell .gshell-panel>.goyo-acc{
    flex:1 1 auto; justify-content:flex-start; flex-wrap:wrap; margin-top:var(--g-2);
    padding-top:var(--g-2); border-top:1px solid var(--g-line-2);
  }
  .gshell .gshell-panel>.goyo-acc .nm{max-width:100%}
  .gshell .gshell-panel>.goyo-acc a,.gshell .gshell-panel>.goyo-acc button.out{
    min-height:var(--g-control); font-size:var(--g-small); padding:0 var(--g-3);
  }
  .gshell .goyo-acc .nm{max-width:9ch}
  .gshell .goyo-acc .say{font-size:var(--g-label)}
  /* compact, not absent: the account answer stays on screen at 390px */
  .gshell .goyo-acc a,.gshell .goyo-acc button.out{padding:0 6px; font-size:var(--g-label)}
  .gshell .gshell-btn{padding:0 var(--g-2)}
}
/* enlarged text and zoom must be able to grow the bar: min-height is a
   floor, never a clip */
.gshell .top .in{flex-wrap:nowrap}

/* ============================================================== page */
.gpage{
  box-sizing:border-box; max-width:var(--g-measure-work); margin:0 auto;
  padding:var(--g-8) var(--g-gutter) var(--g-16);
  font:400 var(--g-body)/var(--g-body-lh) var(--g-sans); color:var(--g-ink);
}
.gpage[data-measure=read]{max-width:calc(var(--g-measure-read) + 2 * var(--g-gutter))}
.gpage[data-measure=form]{max-width:var(--g-measure-form)}
.gpage h1{font:700 var(--g-h1)/var(--g-h1-lh) var(--g-serif); letter-spacing:-.015em; margin:0 0 var(--g-4); text-wrap:pretty}
.gpage h2{font:700 var(--g-h2)/var(--g-h2-lh) var(--g-serif); margin:var(--g-12) 0 var(--g-3); text-wrap:pretty}
.gpage h3{font:700 var(--g-h3)/var(--g-h3-lh) var(--g-sans); margin:var(--g-8) 0 var(--g-2)}
.gpage p{margin:0 0 var(--g-4); max-width:var(--g-measure-read); text-wrap:pretty}
.gpage .lede{font-size:20px; line-height:1.5; color:var(--g-ink-2)}
.gpage a{color:var(--g-navy)}
.gpage a:hover{color:var(--g-navy-h)}

.gcrumbs{
  max-width:var(--g-container); margin:0 auto; box-sizing:border-box;
  padding:var(--g-3) var(--g-gutter) 0;
  font:500 var(--g-label)/1.4 var(--g-sans); color:var(--g-ink-2);
  display:flex; flex-wrap:wrap; gap:var(--g-2); align-items:center;
}
.gcrumbs a{color:var(--g-ink-2)} .gcrumbs b{color:var(--g-ink)}

/* =========================================================== Button */
.gbtn{
  display:inline-flex; align-items:center; justify-content:center; box-sizing:border-box;
  min-height:var(--g-control); padding:0 var(--g-6);
  font:600 var(--g-small)/1 var(--g-sans); text-decoration:none; cursor:pointer;
  color:#fff; background:var(--g-navy); border:1px solid var(--g-navy); border-radius:var(--g-radius);
}
.gbtn:hover{background:var(--g-navy-h); border-color:var(--g-navy-h); color:#fff}
.gbtn:focus-visible{outline:var(--g-focus) solid var(--g-navy); outline-offset:2px}
.gbtn[data-variant=outline]{color:var(--g-navy); background:var(--g-bg)}
.gbtn[data-variant=outline]:hover{background:var(--g-navy-bg); color:var(--g-navy-h)}
.gbtn[data-variant=text]{color:var(--g-navy); background:none; border-color:transparent; padding:0 var(--g-2)}
.gbtn[data-variant=text]:hover{background:var(--g-bg-2)}
.gbtn[data-size=compact]{min-height:var(--g-control-compact); padding:0 var(--g-4); font-size:var(--g-label)}
.gbtn[disabled],.gbtn[aria-disabled=true]{opacity:.5; cursor:not-allowed}
.gbtn[disabled]:hover,.gbtn[aria-disabled=true]:hover{background:var(--g-navy); border-color:var(--g-navy)}
html[data-theme=dark] .gbtn{color:#101B29}
html[data-theme=dark] .gbtn:hover{color:#101B29}
html[data-theme=dark] .gbtn[data-variant=outline],
html[data-theme=dark] .gbtn[data-variant=text]{color:var(--g-navy); background:transparent}
/* .gpage a is (0,1,1) and out-ranked the (0,1,0) .gbtn rule, so an anchor
   button inside a page rendered navy text on a navy fill. The Button owns
   its own colour wherever it is used. */
.gpage a.gbtn,.gcard a.gbtn{color:#fff}
.gpage a.gbtn:hover,.gcard a.gbtn:hover{color:#fff}
.gpage a.gbtn[data-variant=outline],.gpage a.gbtn[data-variant=text],
.gcard a.gbtn[data-variant=outline],.gcard a.gbtn[data-variant=text]{color:var(--g-navy)}
html[data-theme=dark] .gpage a.gbtn,html[data-theme=dark] .gcard a.gbtn{color:#101B29}
html[data-theme=dark] .gpage a.gbtn[data-variant=outline],
html[data-theme=dark] .gpage a.gbtn[data-variant=text]{color:var(--g-navy)}
.gcard[data-tone=brand] a{color:#fff}

.gactions{display:flex; flex-wrap:wrap; gap:var(--g-3); align-items:center}

/* ======================================================== FormField */
.gfield{display:block; margin:0 0 var(--g-6); max-width:var(--g-measure-form)}
.gfield>label,.gfield>legend{
  display:block; padding:0; margin:0 0 var(--g-2);
  font:700 var(--g-label)/1.3 var(--g-sans); letter-spacing:normal; text-transform:none; color:var(--g-ink-2);
}
.gfield .opt{font-weight:500; letter-spacing:0; text-transform:none}
.gfield .hint{margin:0 0 var(--g-2); font:400 var(--g-small)/1.45 var(--g-sans); color:var(--g-ink-2)}
.gfield input[type=text],.gfield input[type=email],.gfield input[type=url],
.gfield input[type=password],.gfield select,.gfield textarea{
  display:block; box-sizing:border-box; width:100%; min-height:var(--g-control);
  padding:var(--g-3); font:400 var(--g-small)/1.4 var(--g-sans); color:var(--g-ink);
  background:var(--g-bg); border:1px solid var(--g-line); border-radius:var(--g-radius);
}
.gfield textarea{min-height:160px; line-height:1.55; resize:vertical}
/* a state selector is a short control, not an empty strip across the row */
.gfield select{max-width:24ch}
.gfield[data-width=short] input{max-width:24ch}
.gfield :focus-visible{outline:var(--g-focus) solid var(--g-navy); outline-offset:2px}
.gfield [aria-invalid=true]{border-color:var(--g-stop); border-width:2px}
.gfield .err{margin:var(--g-2) 0 0; font:600 var(--g-small)/1.4 var(--g-sans); color:var(--g-stop)}
.gfield .err:empty{display:none}
@media (max-width:640px){ .gfield select,.gfield[data-width=short] input{max-width:100%} }

/* ============================================================== Card */
.gcard{
  box-sizing:border-box; background:var(--g-card);
  border:1px solid var(--g-line); border-radius:var(--g-radius-lg); padding:var(--g-6);
}
.gcard>:first-child{margin-top:0} .gcard>:last-child{margin-bottom:0}
.gcard h3{margin-top:0}
.gcard[data-tone=quiet]{background:var(--g-bg-2)}
.gcard[data-tone=brand]{background:var(--g-navy-deep); border-color:var(--g-navy-deep); color:#fff}
.gcard[data-tone=brand] h2,.gcard[data-tone=brand] h3{color:#fff}
.gcard[data-tone=brand] p{color:#E7ECF2}
.ggrid{display:grid; gap:var(--g-4); grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr))}

/* ============================================================ Status */
/* colour is never the only signal: every status carries its own words */
.gstatus{
  display:inline-flex; align-items:center; gap:var(--g-2); box-sizing:border-box;
  min-height:var(--g-control-compact); padding:0 var(--g-3);
  font:600 var(--g-label)/1.3 var(--g-sans);
  border:1px solid var(--g-line); border-radius:var(--g-radius);
  background:var(--g-bg-2); color:var(--g-ink);
}
.gstatus .dot{width:9px; height:9px; border-radius:50%; background:currentColor; flex:0 0 auto}
.gstatus[data-tone=ok]{color:var(--g-ok); background:var(--g-ok-bg); border-color:var(--g-ok)}
.gstatus[data-tone=wait]{color:var(--g-warn); background:var(--g-warn-bg); border-color:var(--g-warn)}
.gstatus[data-tone=stop]{color:var(--g-stop); background:var(--g-stop-bg); border-color:var(--g-stop)}
.gnotice{
  box-sizing:border-box; border:1px solid var(--g-line); border-left:4px solid var(--g-gold);
  border-radius:var(--g-radius); background:var(--g-bg-2); padding:var(--g-4);
  font:400 var(--g-small)/1.5 var(--g-sans); color:var(--g-ink);
}
.gnotice b{display:block; font-family:var(--g-serif); font-size:var(--g-h3); margin-bottom:var(--g-1)}

/* ============================================================ Footer */
.gfoot{border-top:1px solid var(--g-line); background:var(--g-bg-2); margin-top:var(--g-16)}
.gfoot .in{
  box-sizing:border-box; max-width:var(--g-container); margin:0 auto;
  padding:var(--g-6) var(--g-gutter);
  display:flex; flex-wrap:wrap; gap:var(--g-3) var(--g-6); align-items:baseline; justify-content:space-between;
  font:400 var(--g-label)/1.5 var(--g-sans); color:var(--g-ink-2);
}
.gfoot p{margin:0; max-width:70ch}
.gfoot .responsibility{flex-basis:100%; color:var(--g-ink-2)}
.gfoot .brandline{display:flex; align-items:center}
.gfoot .brandline .glockup{--g-mark:28px; --g-wordmark:18px; color:var(--g-ink-2)}
.gfoot .brandline .glockup b i{color:var(--g-ink-2)}
.gfoot nav{display:flex; flex-wrap:wrap; gap:var(--g-4)}
.gfoot a{color:var(--g-ink-2)} .gfoot a:hover{color:var(--g-ink)}

/* skip link: shared, not per page */
.gskip{
  position:absolute; left:-9999px; top:0; z-index:100;
  display:inline-flex; align-items:center; min-height:var(--g-control); padding:0 var(--g-4);
  background:var(--g-bg); color:var(--g-navy); border:2px solid var(--g-navy);
  font:600 var(--g-small)/1 var(--g-sans); text-decoration:none;
}
.gskip:focus{left:var(--g-gutter); top:var(--g-2)}

@media (prefers-reduced-motion:reduce){ .gshell *,.gpage *{transition:none !important; animation:none !important} }
