/* ==========================================================================
   git.guide.

   The token block is Dalaric's, copied from dalaric.com's styles.css rather
   than chosen here. Every pairing used below is one that already appears in
   that site's verified contrast table, which is why this file introduces no
   colour of its own.

   One gap, recorded rather than filled: there is no red in the palette, and a
   critical result wants one. The exposed state therefore uses --gg-warn, the
   existing dark orange. A red is a design record decision and belongs in
   looks.md, not in a stylesheet.
   ========================================================================== */
:root {
  --gg-ink:            #101828;
  --gg-ink-muted:      #465166;
  --gg-surface:        #FFFFFF;
  --gg-surface-alt:    #EEF1F4;
  --gg-accent:         #0B5FA5;
  --gg-accent-hover:   #07456F;
  --gg-accent-soft:    #E3EEF8;
  --gg-border:         #DCE5EF;
  --gg-border-strong:  #6C7A8C;
  --gg-success:        #0B6B57;
  --gg-warn:           #A0480A;
  --gg-surface-deep:   #0B1220;
  --gg-on-deep:        #FFFFFF;
  --gg-on-deep-muted:  #C4CEDD;
  --gg-accent-on-deep: #8FC3F0;
  --gg-border-on-deep: #63718A;

  --gg-radius: 4px;
  --gg-rhythm: 4.5rem;
  --gg-measure: 68ch;
  --gg-container: 1120px;
  --gg-gap: 1.5rem;

  --gg-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
             "Liberation Mono", monospace;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--gg-surface);
  color: var(--gg-ink);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
  font-size: 1.125rem;
  line-height: 1.6;
  font-synthesis-weight: none;
}

h1, h2, h3 {
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 0 0 0.6em;
  font-weight: 640;
}
h1 { font-size: clamp(2.1rem, 1.5rem + 2.6vw, 3.25rem); letter-spacing: -0.03em; }
h2 { font-size: clamp(1.65rem, 1.35rem + 1.3vw, 2.25rem); }
h3 { font-size: 1.1875rem; letter-spacing: -0.01em; }

p, ul, ol { margin: 0 0 1.1em; }
p, li { max-width: var(--gg-measure); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a { color: var(--gg-accent); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { color: var(--gg-accent-hover); }

:focus-visible {
  outline: 3px solid var(--gg-accent);
  outline-offset: 3px;
  border-radius: 2px;
}

code, kbd, samp { font-family: var(--gg-mono); font-size: 0.9em; }

pre {
  background: var(--gg-surface-deep);
  color: var(--gg-on-deep);
  padding: 1.1rem 1.25rem;
  border-radius: var(--gg-radius);
  overflow-x: auto;
  font-size: 0.9375rem;
  line-height: 1.55;
  margin: 0 0 1.4em;
  max-width: 100%;
}
pre code { font-size: inherit; color: inherit; }

.skip {
  position: absolute;
  left: -9999px;
  background: var(--gg-surface);
  color: var(--gg-ink);
  padding: 0.75rem 1rem;
  z-index: 10;
}
.skip:focus { left: 1rem; top: 1rem; }

.container {
  width: min(100% - 2.5rem, var(--gg-container));
  margin-inline: auto;
}

/* ---- header --------------------------------------------------------------- */

/* Sticky, because the guides run to several thousand pixels and a reader who
   wants a different answer should not have to scroll back to the top to find
   the way to it. Pure CSS: this site runs no JavaScript. */
/* Slimmed on 11 September 2026, from 89px to about 52. It is on the screen on
   every page at every scroll position, so its height is a tax on all of them,
   and the strapline it carried is a sentence the home page already makes. */
.site-head {
  background: var(--gg-surface-deep);
  color: var(--gg-on-deep);
  padding: 0.6rem 0;
  position: sticky;
  top: 0;
  z-index: 20;
  border-bottom: 1px solid var(--gg-border-on-deep);
}

/* Anything linked to has to clear the sticky header, or the reader lands with
   the paragraph they wanted hidden behind it. */
:target { scroll-margin-top: 4.5rem; }

/* A phone in landscape has very little height, and a header that takes a fifth
   of it is worse than one that scrolls away. */
@media (max-height: 30rem) {
  .site-head { position: static; }
  :target { scroll-margin-top: 1.5rem; }
}

.site-head__inner {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem var(--gg-gap);
  align-items: center;
  justify-content: space-between;
}
.brand { text-decoration: none; color: inherit; display: block; }
.brand__name {
  display: block;
  font-size: 1.3125rem;
  font-weight: 680;
  letter-spacing: -0.03em;
}
.brand__dot { color: var(--gg-accent-on-deep); }
.site-head nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.4rem;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 1rem;
}
.site-head nav li { max-width: none; }
.site-head nav a { color: var(--gg-on-deep); text-decoration: none; }
.site-head nav a:hover { color: var(--gg-accent-on-deep); text-decoration: underline; }
.site-head nav a[aria-current="page"] {
  color: var(--gg-accent-on-deep);
  text-decoration: underline;
  text-underline-offset: 0.3em;
}

/* ---- the guides menu -----------------------------------------------------
   A details element. No JavaScript exists on this site, and none is needed:
   the browser handles the toggling, the keyboard and the announcement. */

.nav-menu { position: relative; max-width: none; }
.nav-menu summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.nav-menu summary::-webkit-details-marker { display: none; }
.nav-menu summary::after {
  content: "";
  width: 0.42em;
  height: 0.42em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-0.12em, -0.12em);
}
.nav-menu details[open] summary::after { transform: rotate(-135deg) translate(-0.1em, -0.1em); }
.nav-menu summary:hover { color: var(--gg-accent-on-deep); }
.nav-menu summary.is-here {
  color: var(--gg-accent-on-deep);
  text-decoration: underline;
  text-underline-offset: 0.3em;
}
.nav-menu summary:focus-visible { outline: 3px solid var(--gg-accent-on-deep); outline-offset: 3px; }

.nav-menu__panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.85rem);
  width: min(88vw, 32rem);
  background: var(--gg-surface);
  color: var(--gg-ink);
  border: 1px solid var(--gg-border);
  border-radius: var(--gg-radius);
  padding: 1.35rem 1.5rem;
  box-shadow: 0 16px 40px rgb(16 24 40 / 28%);
  z-index: 30;
}
.nav-menu__group {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 680;
  color: var(--gg-ink-muted);
  margin: 1.15rem 0 0.5rem;
  max-width: none;
}
.nav-menu__group:first-child { margin-top: 0; }
/* Scoped for the same reason the links below are. `.site-head nav ul` is a
   wrapping flex row at (0,1,2) and beats a bare `.nav-menu__panel ul`, which
   laid two guides side by side on one line and read as a paragraph rather than
   a list. */
.site-head .nav-menu__panel ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.1rem;
}
.site-head .nav-menu__panel li { max-width: none; }
/* Scoped under .site-head deliberately. The panel sits inside the header, so
   `.site-head nav a` is white at (0,1,2) and beats a bare `.nav-menu__panel a`
   at (0,1,1). That put white links on a white panel at 1:1, which is what
   bin/check-a11y.mjs reported the moment this was written. */
.site-head .nav-menu__panel a {
  display: block;
  padding: 0.4rem 0.6rem;
  margin-left: -0.6rem;
  border-radius: var(--gg-radius);
  color: var(--gg-accent);
  text-decoration: none;
  font-size: 1rem;
}
.site-head .nav-menu__panel a:hover { background: var(--gg-accent-soft); color: var(--gg-accent-hover); }
.site-head .nav-menu__panel a[aria-current="page"] {
  background: var(--gg-accent-soft);
  color: var(--gg-accent-hover);
  text-decoration: none;
  font-weight: 640;
}
.nav-menu__all {
  margin: 1.15rem 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--gg-border);
  max-width: none;
}
.site-head .nav-menu__all a { display: inline; padding: 0; margin: 0; }

/* On a narrow screen the brand and the nav wrapped onto two rows, which made
   the sticky header 95px tall. A little less type gets them onto one.
   
   This sits AFTER the rules it overrides on purpose. A media query adds no
   specificity, so the first attempt at this was placed above .brand__name and
   simply lost to it, with the computed size unchanged at 21px. */
@media (max-width: 30rem) {
  .site-head__inner { gap: 0.5rem 0.9rem; }
  .brand__name { font-size: 1.0625rem; }
  .site-head nav ul { font-size: 0.8125rem; gap: 0.25rem 0.8rem; }
}

/* Narrow screens get it inline instead. A panel anchored to a wrapped nav item
   can end up half off the side of a phone, and expanding in place costs
   nothing here because the header is short. */
@media (max-width: 44rem) {
  .nav-menu__panel {
    position: static;
    width: auto;
    box-shadow: none;
    margin-top: 0.85rem;
  }
}

/* ---- bands ---------------------------------------------------------------- */

.band { padding: var(--gg-rhythm) 0; }
.band--alt { background: var(--gg-surface-alt); }
.band--deep { background: var(--gg-surface-deep); color: var(--gg-on-deep); }
.band--deep h2, .band--deep h3 { color: var(--gg-on-deep); }
/* Not .btn. A plain descendant selector outranks .btn--primary on
   specificity, so without the exclusion it repaints the button's white label
   in the pale link blue and drops it to 3.5:1 against its own blue fill. */
.band--deep a:not(.btn) { color: var(--gg-accent-on-deep); }
.band--deep .eyebrow, .band--deep .note { color: var(--gg-on-deep-muted); }
.band--urgent { background: var(--gg-surface-alt); padding: var(--gg-rhythm) 0; }

.prose > * { max-width: var(--gg-measure); }
.prose > pre, .prose > .table-wrap { max-width: 100%; }

.eyebrow {
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 660;
  color: var(--gg-ink-muted);
  margin-bottom: 0.75rem;
}

.note { color: var(--gg-ink-muted); font-size: 0.9375rem; }

.lead { font-size: 1.3125rem; color: var(--gg-ink-muted); }

/* ---- hero and the form ---------------------------------------------------- */

.hero {
  background: var(--gg-surface-deep);
  color: var(--gg-on-deep);
  padding: calc(var(--gg-rhythm) * 0.9) 0;
}
/* Every page but the home page. Measured on /undo/ before this existed: the
   hero was 369px on a desktop and 507px on a phone, and the first real heading
   sat 1172px down the phone screen. A reader who arrived from a search with a
   question was a full screen of dark chrome away from the answer. The home
   page keeps the generous version, because there the hero is the pitch. */
.hero--compact {
  padding: 1.9rem 0 2.1rem;
}
.hero--compact h1 {
  font-size: clamp(1.85rem, 1.4rem + 1.9vw, 2.6rem);
  margin-bottom: 0.45em;
}
.hero--compact .lead { font-size: 1.125rem; }

.hero h1 { color: var(--gg-on-deep); }
/* The muted greys are for a light band. On this one they land at 2.3:1, so
   both of them are swapped for the pairing that was verified against the dark
   surface rather than against white. */
.hero .lead, .hero .note { color: var(--gg-on-deep-muted); }
.hero a:not(.btn) { color: var(--gg-accent-on-deep); }

.check { max-width: 40rem; margin-top: 2rem; }
.check label {
  display: block;
  font-weight: 620;
  margin-bottom: 0.45rem;
  font-size: 1rem;
}
.hero .check label { color: var(--gg-on-deep); }
.check__row { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.check input {
  flex: 1 1 16rem;
  min-width: 0;
  font: inherit;
  padding: 0.8rem 0.9rem;
  border: 2px solid var(--gg-border-strong);
  border-radius: var(--gg-radius);
  background: var(--gg-surface);
  color: var(--gg-ink);
}
.check button {
  font: inherit;
  font-weight: 640;
  padding: 0.8rem 1.6rem;
  border: 2px solid var(--gg-accent);
  border-radius: var(--gg-radius);
  background: var(--gg-accent);
  color: #FFFFFF;
  cursor: pointer;
}
.check button:hover { background: var(--gg-accent-hover); border-color: var(--gg-accent-hover); }

/* ---- the result ----------------------------------------------------------- */

.result {
  background: var(--gg-surface-alt);
  border-left: 6px solid var(--gg-border-strong);
  padding: 1.75rem;
  border-radius: var(--gg-radius);
  margin-bottom: 1.5rem;
}
.result--bad { border-left-color: var(--gg-warn); }
.result--good { border-left-color: var(--gg-success); }
.result--warn { border-left-color: var(--gg-ink-muted); }

.result__label {
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 700;
  margin-bottom: 0.5rem;
}
.result--bad .result__label { color: var(--gg-warn); }
.result--good .result__label { color: var(--gg-success); }
.result--warn .result__label { color: var(--gg-ink-muted); }

/* An h1, because the verdict is what the page is about, sized like an h2
   because it sits inside a card rather than across the top of a page. */
.result__headline {
  margin-bottom: 0.5rem;
  font-size: clamp(1.65rem, 1.35rem + 1.3vw, 2.25rem);
}
.result__host { color: var(--gg-ink-muted); font-size: 0.9375rem; }
.result__notes { margin: 1.1em 0 0; padding-left: 1.2rem; }
.result__notes li { margin-bottom: 0.5em; }

/* ---- lists, steps and cards ----------------------------------------------- */

.steps { list-style: none; counter-reset: step; margin: 0; padding: 0; }
.steps > li {
  counter-increment: step;
  position: relative;
  padding-left: 3rem;
  margin-bottom: 1.75rem;
  max-width: var(--gg-measure);
}
.steps > li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--gg-accent-soft);
  color: var(--gg-accent-hover);
  font-weight: 700;
  font-size: 0.9375rem;
  display: grid;
  place-items: center;
}
.band--deep .steps > li::before { background: var(--gg-accent-on-deep); color: var(--gg-surface-deep); }
.steps h3 { margin-bottom: 0.35em; }

.cards {
  display: grid;
  gap: var(--gg-gap);
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  margin-top: 2rem;
}
.card {
  background: var(--gg-surface);
  border: 1px solid var(--gg-border);
  border-radius: var(--gg-radius);
  padding: 1.5rem;
  transition: border-color 0.12s ease, transform 0.12s ease;
}
/* A card that is entirely a link should say so on the way past. Movement is
   small and is turned off under reduced motion, further down. */
.card:has(a):hover { border-color: var(--gg-accent); transform: translateY(-2px); }
.band--deep .card {
  background: transparent;
  border-color: var(--gg-border-on-deep);
}
.card h3 { margin-bottom: 0.4em; }
.card p, .card li { max-width: none; }
.card > :last-child { margin-bottom: 0; }

/* A gap above a closing line or a note that follows a block. Was six inline
   style attributes until 11 September 2026, when a browser console showed the
   content security policy had been blocking every one of them since the policy
   was written: style-src 'self' refuses a style attribute, so none of those
   margins had ever applied. A class works and keeps the policy strict. */
.spaced { margin-top: 2rem; }

/* ---- finding an answer ----------------------------------------------------
   Three blocks for the reader who arrived with a question rather than an
   interest in the subject. All three are generated in build.mjs. */

/* The contents list at the top of a long guide. Bordered rather than filled,
   so it reads as apparatus and does not compete with the first section. */
.contents {
  max-width: var(--gg-measure);
  margin: 0 auto;
  padding: 1.1rem 1.35rem;
  font-size: 0.9375rem;
  line-height: 1.45;
  border: 1px solid var(--gg-border);
  border-left: 4px solid var(--gg-accent);
  border-radius: var(--gg-radius);
  background: var(--gg-surface);
}
.contents__head {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gg-ink-muted);
  margin-bottom: 0.7rem;
}
.contents ol {
  margin: 0;
  padding-left: 1.3rem;
  columns: 2;
  column-gap: 2rem;
}
.contents li {
  margin-bottom: 0.3rem;
  max-width: none;
  break-inside: avoid;
}
@media (max-width: 26rem) { .contents ol { columns: 1; } }

/* Wraps the contents list in its own band so it sits between the hero and the
   first section rather than on top of one of them. Tightened along with the
   hero: it was 336px on a desktop and 512px on a phone, which is a lot of
   apparatus to scroll past on the way to the thing it points at. */
.contents-band { padding: 1.75rem 0 0; }

/* A question and its answer. The rule on the left is what makes a run of them
   scannable: the eye follows the edge down and stops at the one that matches,
   which a run of bold paragraphs does not do. */
.qa { margin-top: 2rem; max-width: var(--gg-measure); }
.qa__item {
  padding: 1.1rem 0 1.1rem 1.25rem;
  border-left: 3px solid var(--gg-border);
  margin-bottom: 0.35rem;
}
.qa__item:target { border-left-color: var(--gg-accent); }
.qa__item h3 { margin-bottom: 0.5em; color: var(--gg-ink); }
.qa__item p { margin-bottom: 0.6em; }
.qa__item > :last-child { margin-bottom: 0; }

/* The index at /answers/. */
.answers__group { margin-bottom: 2.25rem; }
.answers__group h3 { margin-bottom: 0.6em; }
.answers__list { list-style: none; margin: 0; padding: 0; }
.answers__list li {
  padding: 0.4rem 0 0.4rem 1.1rem;
  border-left: 2px solid var(--gg-border);
  max-width: var(--gg-measure);
}
.answers__list a { text-decoration-thickness: 1px; }

/* ---- breadcrumb and pager ------------------------------------------------ */

.crumbs { margin-bottom: 1.5rem; font-size: 0.9375rem; }
.crumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.65rem;
  list-style: none;
  margin: 0;
  padding: 0;
  color: var(--gg-on-deep-muted);
}
.crumbs li { max-width: none; display: flex; align-items: center; gap: 0.65rem; }
.crumbs li + li::before { content: "/"; color: var(--gg-border-on-deep); }
.crumbs a { color: var(--gg-accent-on-deep); }

.pager {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--gg-gap);
}
.pager__link {
  display: block;
  padding: 1.1rem 1.35rem;
  border: 1px solid var(--gg-border);
  border-radius: var(--gg-radius);
  text-decoration: none;
  background: var(--gg-surface);
}
.pager__link:hover { border-color: var(--gg-accent); }
.pager__link--next { text-align: right; }
.pager__label {
  display: block;
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 660;
  color: var(--gg-ink-muted);
  margin-bottom: 0.3rem;
}
.pager__title { display: block; font-weight: 620; }

/* A heading arrived at from a link should be obvious, or the reader lands
   mid page and has to work out which paragraph was the point. */
h2:target, h3:target {
  background: var(--gg-accent-soft);
  box-shadow: 0 0 0 0.4rem var(--gg-accent-soft);
  border-radius: 2px;
}

.table-wrap { overflow-x: auto; margin-bottom: 1.4em; }
table { border-collapse: collapse; width: 100%; font-size: 1rem; }
th, td {
  text-align: left;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--gg-border);
  vertical-align: top;
}
th { font-weight: 660; }
thead th { border-bottom: 2px solid var(--gg-border-strong); }

.actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.75rem; }
.btn {
  display: inline-block;
  font-weight: 640;
  padding: 0.75rem 1.5rem;
  border-radius: var(--gg-radius);
  text-decoration: none;
  border: 2px solid transparent;
}
.btn--primary { background: var(--gg-accent); color: #FFFFFF; border-color: var(--gg-accent); }
.btn--primary:hover { background: var(--gg-accent-hover); border-color: var(--gg-accent-hover); color: #FFFFFF; }
.btn--secondary { border-color: var(--gg-border-strong); color: var(--gg-accent); }
.btn--secondary:hover { border-color: var(--gg-accent); color: var(--gg-accent-hover); }
.band--deep .btn--secondary { border-color: var(--gg-border-on-deep); color: var(--gg-accent-on-deep); }

/* WCAG 2.2 SC 1.4.11. The accent fill is 6.57:1 on white and a comfortable
   5.80:1 on the alt band, but only 2.85:1 against the deep surface, so on a
   dark band the button's own edge is what tells you a button is there and it
   was not doing it. The outline is accent-on-deep at 10.01:1 against the band.
   Caught by bin/check-a11y.mjs, which exists because the contrast pass alone
   is blind to this: it compares a label against its own button, so a button
   that has vanished into the page still scores perfectly. */
.band--deep .btn--primary,
.hero .btn--primary,
.hero .check button { border-color: var(--gg-accent-on-deep); }

/* ---- footer --------------------------------------------------------------- */

.site-foot {
  background: var(--gg-surface-deep);
  color: var(--gg-on-deep-muted);
  padding: var(--gg-rhythm) 0 2.5rem;
  font-size: 1rem;
}
.site-foot h2 {
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gg-on-deep);
  margin-bottom: 0.9rem;
}
.site-foot a { color: var(--gg-accent-on-deep); }
.site-foot ul { list-style: none; margin: 0; padding: 0; }
.site-foot li { margin-bottom: 0.5rem; max-width: none; }
.site-foot__grid {
  display: grid;
  gap: 2.5rem var(--gg-gap);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.site-foot__who p { color: var(--gg-on-deep-muted); font-size: 0.9375rem; }
.site-foot__who strong { color: var(--gg-on-deep); }
.mark { width: 40px; height: 40px; display: block; margin-bottom: 1rem; }
.site-foot__legal {
  margin-top: 2.5rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--gg-border-on-deep);
  font-size: 0.875rem;
}
.site-foot__legal p { max-width: none; margin-bottom: 0.4rem; }

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