/*
 * **The brand, in a layer of its own**, KAN-84: the marketing pages' `mk-*`, the bars'
 * colours, the hero, the footer, the booking steps.
 *
 * **Above the components and below the utilities**, so `mk-nav` can recolour a
 * `ui-navbar` and `mk-btn` can reshape a `ui-btn`, while a utility on the element still
 * says the last word. Unlayered, as this file was, it beat every utility on the page, and
 * the order is stated here and again at the top of the React stylesheet because layer
 * order is fixed by whichever statement the browser meets first.
 */
@layer properties, theme, base, components, brand, utilities;

@layer brand {
/*
  Honeypot field on the contact forms. Positioned off-screen rather than hidden
  with display:none, because some spam bots skip fields they can tell are
  hidden. Real visitors never see or tab into it, so it should stay empty.
*/
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/*
  The footer, in the logo's slate with the logo's gold as the line above it.

  It used to be #57ACD6 with near-white text on it, which measures about 2.4:1
  and is below what anybody can comfortably read. Slate carries white at 9:1 and
  is the colour the wordmark is drawn in, so the band and the logo standing in it
  are the same grey.
*/
/*
  The footer never sits in the first screenful, however little a page holds.

  **A short page used to end halfway down and put the slate band across the middle of the
  screen**, which reads as the page having finished when it has not: on an admin page with
  two controls on it the eye lands on the footer rather than on the controls, and on the
  editor pages the amount of content varies with how many panes are open, so the band
  moved about between one task and the next.

  `min-height: 100dvh` on `main` is what fixes it, and it is on `main` rather than on the
  footer for a reason: a `position: fixed` footer would cover content instead of following
  it, and `margin-top: auto` in a flex column only pushes it to the bottom of the
  *viewport*, which is precisely where it must not be. Making the content itself at least
  a screen tall puts the footer one full screen down, whatever is above it.

  **`dvh` and not `vh`**, because on a phone `100vh` is measured against the viewport with
  the browser's own bars retracted: the difference is about the height of the address bar,
  which is enough to leave the top of the slate band showing before anybody scrolls. `dvh`
  is the height as it actually is at that moment. Every browser this site supports has it;
  a `vh` fallback goes first for anything that does not, where the old behaviour is no
  worse than it was.
*/
main {
  min-height: 100vh;
  min-height: 100dvh;
}

.site-footer {
  background-color: var(--mt-slate);
  color: #fff;
  /* The logo's third colour, used the only way it can be, as a line. */
  border-top: 3px solid var(--mt-gold);
}

.site-footer a {
  color: #fff;
  text-decoration-color: rgba(255, 255, 255, .5);
}

.site-footer a:hover {
  color: #fff;
  text-decoration-color: #fff;
}

/* The language picker, KAN-365: each language is a submit button in a form, so it works
   with no script, and is drawn as the footer's links are so it reads as a choice of
   places rather than a row of controls. */
.mk-language button {
  font: inherit;
  color: #fff;
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, .5);
}

.mk-language button:hover,
.mk-language button:focus-visible {
  text-decoration-color: #fff;
}

/*
  The Tests column in the file list. A tick with a count beside it: green when
  every test passed, amber when the tests ran and some did not.
*/
.test-cell-inner {
  display: flex;
  align-items: center;
  gap: .5rem;
}

.test-result {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  white-space: nowrap;
  font-size: .9rem;
}

.test-tick {
  font-size: 1.15rem;
  line-height: 1;
}

.test-pass {
  color: #146c43; /* Bootstrap's success emphasis: passes contrast on white. */
}

/*
  Deliberately not Bootstrap's #ffc107 warning yellow, which is far too light to
  read as text on a white table row.
*/
.test-partial {
  color: #997404;
}

.test-error {
  color: #b02a37;
}

/* Keeps the row from jumping about while a test run is in flight. */
.test-cell {
  min-width: 11rem;
}
/* The small capitals above a heading. They say which part of the site you are
   in without spending a whole line on it. */
.eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  font-weight: 700;
}

/*
  The claims worth making immediately, on one line, separated by dots. A list
  rather than a sentence because nobody reads a sentence in a hero, they scan
  it for the words that matter.
*/
/**
 * The two sign-up buttons, which are a pair and are drawn as one.
 *
 * **Equal width, not equal wording.** They offer the same thing to two audiences, so a
 * reader picks between them on the words rather than on which looks like the bigger
 * button; left to their text they come out a few pixels apart, which reads as one being
 * the real choice. The labels are the same length anyway, and this keeps them level when
 * one of them is next reworded.
 *
 * **Grown from a shared basis, not held at a `min-width`.** A minimum only makes them
 * equal while both labels are shorter than it: reword one past the floor and the pair
 * diverges again, silently, and the first version of this looked right only because the
 * two happened to render within a pixel of each other. Equal `flex-basis` and equal
 * `flex-grow` divide whatever the row has between them, so they come out the same width
 * whatever they say.
 *
 * The basis is what they fall back to when the row is too narrow for both, at which point
 * they wrap and each takes a line; the cap stops them stretching the width of a hero.
 */
.mk-btn-audience {
  flex: 1 1 15rem;
  max-width: 20rem;
}

.trust-strip {
  list-style: none;
  padding: 0;
  margin: 1.5rem 0 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.35rem 1.25rem;
  font-size: 0.9rem;
}

.trust-strip li::before {
  content: "\00b7";
  margin-right: 1.25rem;
  opacity: 0.6;
}

/* No dot before the first one, and none at the start of a wrapped line is not
   worth chasing, the gap does that job. */
.trust-strip li:first-child::before {
  content: "";
  margin-right: 0;
}

/* ---------------------------------------------------------------------------
   The palette, read off static/logo.svg.

   The logo is drawn in three colours and nothing else: a slate the wordmark and
   most of the emblem are set in, a cyan, and a gold. Everything on the site is
   one of those three or a tone of one of them, which is the whole point, a
   visitor should not be able to tell the pages and the logo were made at
   different times.

   Two of the three cannot carry white text. Cyan #23ADE3 measures 2.6:1 against
   white and the gold 2.4:1, both well under the 4.5:1 WCAG asks for, so the cyan
   has a darker tone of the same hue for anything with words on it, and the gold
   is only ever an accent: a rule, a border, a dot. Text never sits on it.
   --------------------------------------------------------------------------- */

:root {
  --mt-slate: #3E4A54;       /* the wordmark. White on it: 9.1:1 */
  --mt-slate-dark: #333D46;  /* hover and pressed, above */
  --mt-cyan: #23ADE3;        /* the emblem's blue, for shapes and not for text */
  --mt-cyan-deep: #15769C;   /* the same hue, dark enough either way: 5.1:1 */
  --mt-cyan-darker: #0F5D7D;
  --mt-gold: #D69C28;        /* an accent, never behind words */
  --mt-off-white: #F4F7F7;   /* the logo's own background */

  --mt-primary: #15769C;     /* the one colour meant to be pressed, `--primary` */
}

/* The number on a step. A circle, because three of them in a row read as a
   sequence and three bullet points do not. */
.step-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background-color: var(--mt-cyan-deep);
  color: #fff;
  font-weight: 700;
}

/* The rate on a pricing card: the thing the eye should land on first. */
.tier-price {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1;
}

.tier-price .tier-unit {
  font-size: 0.95rem;
  font-weight: 400;
  opacity: 0.7;
}

/*
  A photograph at the top of a card. Cropped to a consistent band so two cards
  side by side line up whatever shape the picture is.
*/
.card-photo {
  height: 200px;
  object-fit: cover;
  width: 100%;
}

/*
  The same picture, mirrored. Two cards side by side showing the identical band
  reads as a copy-paste mistake; shifting the crop was not enough on an image
  this symmetrical, so this flips it and the pair reads as deliberate.
*/
.card-photo-right {
  transform: scaleX(-1);
}

/* A card that lifts slightly under the cursor: enough to say it is worth
   looking at, not enough to move the page about. */
.lift {
  transition: transform .15s ease, box-shadow .15s ease;
}

.lift:hover {
  transform: translateY(-2px);
  box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .1) !important;
}

@media (prefers-reduced-motion: reduce) {
  .lift {
    transition: none;
  }
  .lift:hover {
    transform: none;
  }
}

/*
  The band at the foot of a page, holding the one action somebody should take if
  they read that far. The deep cyan rather than the slate, because the footer
  directly under it is slate and two slate bands in a row read as one long empty
  stretch. The gold line under it belongs to the footer, so a page without one of
  these bands gets the same line in the same place.
*/
.cta-band {
  background-color: var(--mt-cyan-deep);
  color: #fff;
}

.cta-band a.ui-btn-light {
  font-weight: 600;
}


/* ---------------------------------------------------------------------------
   One palette and one set of edges for both halves, #222.

   The Bootstrap furniture around a signed-in page and the shadcn body inside it are
   given the same ink, the same hairline, the same radii and the same quiet card, so
   the join between them cannot be seen. The values are the web app's own tokens in
   `apps/web/src/styles.css`, spelt twice because the two stylesheets never import
   each other; `contrast.spec.ts` reads both.
   --------------------------------------------------------------------------- */
:root {
  --mt-ink: #1B2430;
  --mt-ink-2: #4B5563;
  --mt-line: #D6DDE3;
  --mt-surface: #F7F9FA;
  /* **Two radii and no more**, KAN-98: 10px on everything pressed or typed into, a button,
     a field, a tag, `--radius` and `--radius-md` on the React side; 14px on everything
     that holds them, a card, a panel, a marketing card, `--radius-xl` there.
     `onesystem.spec.ts` holds both halves to these. */
  --mt-radius: .625rem;
  --mt-radius-card: .875rem;
}

/* ---------------------------------------------------------------------------
   The logo, where a page shows it.
   --------------------------------------------------------------------------- */

/* The emblem beside the company name in the bar. Sized in rem so it grows with
   the user's text size rather than staying put while the words beside it move. */
.brand-mark {
  height: 2.25rem;
  width: 2.25rem;
}

.ui-navbar-brand {
  color: var(--mt-slate);
  font-weight: 600;
}

.ui-navbar-brand:hover {
  color: var(--mt-slate-dark);
}

/* The whole lockup, standing in the footer's slate. Only logo-light.svg is
   right on that background, see the comment in the file.
   `display: block` and `margin: 0 auto` are needed because Tailwind's
   preflight resets <img> to `display: block`, which makes `text-align: center`
   on the parent ineffective. A block element centres with auto side margins. */
.footer-logo {
  height: 6rem;
  display: block;
  margin: 0 auto;
}

/* The emblem over a sign-in card. Without the name, because the bar above it
   has the name and a page this small does not need it twice. */
.auth-mark {
  height: 3.25rem;
  width: 3.25rem;
}

/* ---------------------------------------------------------------------------
   The booking flow.

   The same band as the pages that sell the thing, taken down in size. Somebody
   arriving from the coaching page should not feel they have been handed to a
   different site at the point of paying, but a form is not a pitch either, so
   the type is smaller and there is no photograph carrying half the page.
   --------------------------------------------------------------------------- */

/* Where you are in the flow. Wraps to two lines on a phone rather than
   scrolling sideways, because a trail you have to drag to read is worse than no
   trail at all. */
.book-steps {
  list-style: none;
  padding: 0;
  margin: 1.25rem 0 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .4rem 1rem;
  font-size: .8rem;
}

.book-steps li {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  opacity: .7;
}

.book-steps li.is-now {
  opacity: 1;
  font-weight: 600;
}

.book-steps .step-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .55);
  font-size: .7rem;
  line-height: 1;
}

/* Filled for everything up to and including where you are, so the trail shows
   progress at a glance without a bar to misread. */
.book-steps li.is-now .step-dot,
.book-steps li.is-done .step-dot {
  background-color: #fff;
  border-color: #fff;
  color: var(--mt-cyan-deep);
  font-weight: 700;
}

/* The rate table on the booking pages: figures in a column, so the reader
   compares them by eye instead of parsing four of them out of a sentence. */
.rate-list {
  font-size: .9rem;
}

.rate-list td {
  padding: .35rem 0;
}

.rate-list td:last-child {
  text-align: right;
  font-weight: 600;
  white-space: nowrap;
}

/* The cookie banner. A bar at the bottom rather than a box in the middle: it has
   to be answerable without getting in the way of what somebody came to read, and
   nothing behind it is blocked while it waits. Same slate and gold as the footer
   it sits under, so it reads as part of the site and not as an advert. */
.cookie-consent {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1080;              /* over the sticky editor bars, under a modal */
  background-color: var(--mt-slate);
  color: #fff;
  border-top: 3px solid var(--mt-gold);
  box-shadow: 0 -.5rem 1rem rgba(0, 0, 0, .25);
}

.cookie-consent a {
  color: #fff;
}

/* Both buttons the same, deliberately: a bright Accept beside a faint Reject is
   the usual way one of these stops being a free choice. */
.cookie-consent .ui-btn {
  min-width: 6rem;
}
/* **The same width, always**, which is what the law needs rather than what a min-width
   gave: with Inter, "Accept" and its icon outgrew 6rem while "Reject" did not, and the
   Accept button came out wider. Equal columns in a grid cannot differ. */
.cookie-choices {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
}

@media print {
  .cookie-consent {
    display: none !important;
  }
}

/* A task's description, beside the code. Long enough to need its own scrollbar:
   four hundred words is the length the people writing these asked for, and a panel
   that grows to fit would push Run and the output off the screen. The measure is
   narrow already, being a column, so the height is the only thing to hold. */
.task-description {
  max-height: 22rem;
  overflow-y: auto;
  /* Rendered Markdown now, not raw text, so the paragraphs are real elements and
     pre-wrap would double the spacing. See markdownish.py. */
  font-size: .925rem;
  line-height: 1.6;
}

/* A hint that there is more below, rather than a scrollbar nobody notices. */
.task-description::after {
  content: "";
  display: block;
  height: .25rem;
}

/* Markdown inside the description pane: tighter than the page's defaults, because
   this is a column beside an editor rather than an article. */
.task-description h4,
.task-description h5,
.task-description h6 {
  font-size: 1rem;
  font-weight: 600;
  margin: .75rem 0 .35rem;
}

.task-description p,
.task-description ul,
.task-description ol {
  margin-bottom: .6rem;
}

.task-description pre {
  background: rgba(0, 0, 0, .05);
  border-radius: .25rem;
  padding: .5rem .6rem;
  margin-bottom: .6rem;
  overflow-x: auto;
}

.task-description code {
  font-size: .85em;
}

.task-description blockquote {
  border-left: 3px solid rgba(0, 0, 0, .15);
  margin: 0 0 .6rem;
  padding-left: .6rem;
  color: #555;
}

/* The same pane on the Markdown task's own page, where it is the page rather than a
   column beside an editor: it matches the height of the box it sits next to instead
   of being the short scrolling panel a student reads. */
.task-description-tall {
  max-height: none;
  overflow-y: visible;
}

/* The editing box, which is Markdown source and reads better in a mono font. */
.task-description-edit {
  font-family: var(--font-mono);
  font-size: .85rem;
  line-height: 1.5;
}

/* The conversation about a task, oldest first with the newest at the bottom. Here
   because a task made of words is read on a page with no editor on it, and carries the
   same thread. */
.comment-list {
  max-height: 22rem;
  overflow-y: auto;
}

.comment {
  border-left: 3px solid #dee2e6;
  padding: .25rem 0 .25rem .625rem;
  margin-bottom: .75rem;
}

/* Your own words, so a thread can be read at a glance. */
.comment-mine {
  border-left-color: var(--mt-primary);
}

.comment:last-child {
  margin-bottom: 0;
}

.comment-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .25rem;
}

.comment-body {
  font-size: .9375rem;
  white-space: pre-wrap;
  word-break: break-word;
}

/* The quiz builder. Ours, so its furniture is here rather than coming with a library:
   see frontend/apps/web/src/features/quizbuilder. */
.quiz-list {
  min-height: 4rem;
}

/* The empty state, which reads as somewhere a question will go. */
.border-dashed {
  border-style: dashed !important;
}


/* ---------------------------------------------------------------------------
   Renaming, as a pencil beside a heading.

   `<details>` is the whole mechanism: it opens and closes with no JavaScript, so the
   control works on the first paint rather than waiting for the React bundle, which is
   the reason it is here and not in the app. What it needs from CSS is only to stop
   looking like a disclosure widget: the marker goes, and the summary is a button.
   --------------------------------------------------------------------------- */
details.rename > summary {
  list-style: none;          /* Firefox */
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

details.rename > summary::-webkit-details-marker {
  display: none;             /* Safari and Chrome */
}

/* Open, the form sits under the heading rather than pushing it about: the title is what
   somebody is reading, and it should not move when the pencil is pressed. */
details.rename {
  position: relative;
}

details.rename > form {
  position: absolute;
  z-index: 5;
  top: 100%;
  left: 0;
  min-width: 22rem;
  padding: 0.5rem;
  border: 1px solid var(--mt-line);
  border-radius: 0.375rem;
  background: var(--card);
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}


/* ---------------------------------------------------------------------------
   Typography, #222.

   Inter, self-hosted and variable, on every page of both halves: the system stack
   rendered the site in San Francisco on a Mac, Segoe on a school PC and Roboto on a
   phone, three different products depending on who was looking. Self-hosted because a
   font from a third party is a request to a third party on every page, which `/privacy`
   would have to describe; OFL, `LICENSES.md`. `swap`, so words are never invisible while
   it arrives. One latin file per style, 48 KB, which covers every language the site is
   written in.
   --------------------------------------------------------------------------- */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/static/vendor/inter/inter-latin-wght-normal.woff2") format("woff2-variations");
}
@font-face {
  font-family: "Inter";
  font-style: italic;
  font-display: swap;
  font-weight: 100 900;
  src: url("/static/vendor/inter/inter-latin-wght-italic.woff2") format("woff2-variations");
}
/* **Japanese faces after Inter and before the generic**, KAN-366: Inter has no kana or
   kanji, so those characters fall through to the first face that has them, and naming the
   Japanese system faces here is what stops a browser choosing a Chinese one for Japanese
   text. Latin text never reaches them, so nothing changes on an English or French page,
   and a reader who chose a font of their own still gets it, this being only the default. */
:root {
  --mt-font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial,
    "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic UI", "Yu Gothic", Meiryo,
    "Noto Sans JP", sans-serif;
}
body {
  font-family: var(--mt-font);
  /* Inter's own alternates that make it read as a product face: the open digits, the
     single-storey a is left alone, and a straight-legged l that cannot be read as 1. */
  font-feature-settings: "cv05", "cv08", "ss03";
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
/* Figures that line up wherever numbers are compared: prices, counts, marks. */
.mk-price, .mk-stat, .tabular-nums { font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------------
   The marketing pages. #210.

   One vocabulary for every page that sells the platform, so the pages cannot drift:
   a white page, one large typographic headline, the real product in a browser frame,
   a strip of facts, feature sections that alternate sides, a band of figures, one
   price and one closing call to action. Every colour here is one of the logo's three
   or a tone of one of them, `:root` above, and every pair with words on it was measured
   at 4.5:1. Nothing moves unless the reader has not asked it not to.
   --------------------------------------------------------------------------- */

:root {
  --mk-ink: #1B2430;         /* headings. On white: 15.6:1 */
  --mk-ink-2: #4B5563;       /* body copy beside a heading. On white: 7.6:1 */
  /* **A 4pt scale, KAN-60**, which is the whole of the spacing this system offers. A
     margin typed in rems on one section and picked by eye on the next is how a page comes
     to have five gaps that are nearly the same, which reads as careless without anybody
     being able to say why. The names are the multiple of 4, so `--mk-space-6` is 24px and
     the arithmetic is done by reading. */
  --mk-space-1: 0.25rem;
  --mk-space-2: 0.5rem;
  --mk-space-3: 0.75rem;
  --mk-space-4: 1rem;
  --mk-space-6: 1.5rem;
  --mk-space-8: 2rem;
  --mk-space-12: 3rem;
  --mk-space-16: 4rem;
  --mk-shadow: 0 24px 60px -24px rgba(27, 36, 48, .35), 0 10px 24px -14px rgba(27, 36, 48, .22);
}

.mk { color: var(--mk-ink); }
.mk p { color: var(--mk-ink-2); }
.mk h1, .mk h2, .mk h3, .mk .mk-display, .mk .mk-h2 { color: var(--mk-ink); letter-spacing: -0.02em; line-height: 1.12; }

/* clamp() rather than breakpoints: the headline has to look deliberate at every width. */
.mk-display {
  font-size: clamp(2.4rem, 5.2vw, 4rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.04;
  text-wrap: balance;
}
.mk-h2 { font-size: clamp(1.7rem, 3.2vw, 2.4rem); font-weight: 800; text-wrap: balance; }
.mk-h3 { font-size: 1.15rem; font-weight: 700; }
.mk-lead { font-size: clamp(1.05rem, 1.6vw, 1.25rem); line-height: 1.55; max-width: 36rem; }
.mk-eyebrow { color: var(--mt-cyan-deep); text-transform: uppercase; letter-spacing: .1em; font-size: .75rem; font-weight: 700; }
.mk-measure { max-width: 62ch; }

.mk-section { padding: clamp(3rem, 7vw, 6rem) 0; }
.mk-section.mk-tint { background: var(--mt-off-white); }
.mk-section.mk-ink { background: var(--mt-slate); color: #fff; }
.mk-section.mk-ink h2, .mk-section.mk-ink h3, .mk-section.mk-ink p, .mk-section.mk-ink .mk-h2 { color: #fff; }
.mk-section.mk-ink p { color: rgba(255, 255, 255, .85); }
.mk-section.mk-ink .mk-eyebrow { color: var(--mt-gold); }

/* The hero: words on the left, the product on the right, and the product is a real
   screenshot rather than a photograph of somebody at a laptop. */
.mk-hero { padding: clamp(2.5rem, 6vw, 5rem) 0 clamp(2rem, 5vw, 4rem); }
.mk-hero .mk-window { margin-top: 2rem; }
@media (min-width: 992px) {
  .mk-hero .mk-window { margin-top: 0; }
}
.mk-proof { font-size: .9rem; color: var(--mk-ink-2); }

/* A browser window around a screenshot, so the picture reads as the product rather
   than as an image. */
.mk-window {
  background: var(--card);
  border: 1px solid var(--mt-line);
  border-radius: var(--mt-radius-card);
  box-shadow: var(--mk-shadow);
  overflow: hidden;
}
.mk-window-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: .55rem .85rem;
  background: #F1F3F5;
  border-bottom: 1px solid var(--mt-line);
}
.mk-window-bar i { width: 10px; height: 10px; border-radius: 50%; background: #CBD2D9; }
.mk-window-url {
  flex: 1;
  margin-left: .6rem;
  padding: .15rem .6rem;
  background: var(--card);
  border: 1px solid var(--mt-line);
  border-radius: 6px;
  font-size: .72rem;
  color: #6B7280;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mk-window img { display: block; width: 100%; height: auto; }

/* The strip of facts under the hero. Facts, because that is what gets scanned. */
.mk-strip {
  border-top: 1px solid var(--mt-line);
  border-bottom: 1px solid var(--mt-line);
  padding: 1rem 0;
}
.mk-strip ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .5rem 2rem;
  font-size: .92rem;
  color: var(--mk-ink-2);
}
.mk-strip strong { color: var(--mk-ink); font-weight: 700; }

/* A feature: words one side, the product the other, and the sides swap down the page. */
/* `minmax(0, 1fr)` and `min-width: 0`, #220: a grid cell's floor is its content, and the
   address line in a browser frame does not wrap, so on a 360px phone the cell grew past
   the screen and took the page with it. */
.mk-feature { display: grid; grid-template-columns: minmax(0, 1fr); gap: 2rem; align-items: center; }
.mk-feature > * { min-width: 0; }
.mk-feature + .mk-feature { margin-top: clamp(3rem, 7vw, 6rem); }
/* A student's VM terminal, drawn rather than photographed, KAN-356: a terminal is dark in
   every theme, so its colours are its own and pass AA on #11161d. */
.mk-vmshot pre { background: #11161d; color: #e6edf3; box-shadow: 0 10px 30px rgba(17, 22, 29, .25);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; white-space: pre-wrap; }
.mk-vmshot-prompt { color: #7ee787; }
.mk-vmshot-dim { color: #a5b1bd; }
.mk-vmshot-cursor { color: #e6edf3; }
@media (prefers-reduced-motion: no-preference) {
  .mk-vmshot-cursor { animation: mk-vmshot-blink 1.1s steps(1) infinite; }
}
@keyframes mk-vmshot-blink { 50% { opacity: 0; } }
@media (min-width: 992px) {
  .mk-feature { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 4rem; }
  .mk-feature.mk-flip .mk-feature-text { order: 2; }
}
.mk-ticks { list-style: none; padding: 0; margin: 1.25rem 0 0; }
.mk-ticks li { position: relative; padding-left: 1.9rem; margin-bottom: .6rem; color: var(--mk-ink-2); }

/* /build, KAN-348: big choices, each the whole card a link. One column on a phone, two by
   two from a tablet up, KAN-361, four in a row of three having left one on its own; the
   icon is decoration, the words say it all. */
.mk-choices { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.25rem; }
@media (min-width: 768px) { .mk-choices { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.mk-choice {
  display: flex; flex-direction: column; gap: .75rem; height: 100%;
  padding: clamp(1.5rem, 3vw, 2rem); border: 1px solid var(--mt-line);
  border-radius: var(--mt-radius-card);
  background: var(--card); color: var(--mt-ink); text-decoration: none;
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.mk-choice:hover, .mk-choice:focus-visible {
  border-color: var(--mt-cyan-deep); box-shadow: 0 10px 30px rgba(27, 36, 48, .1);
  transform: translateY(-2px); color: var(--mt-ink);
}
.mk-choice-icon {
  display: grid; place-items: center; width: 4.5rem; height: 4.5rem; border-radius: 1rem;
  background: var(--mt-off-white); color: var(--mt-cyan-deep);
}
.mk-choice h2 { font-size: 1.4rem; font-weight: 800; margin: .25rem 0 0; }
.mk-choice p { color: var(--mk-ink-2); margin: 0; }
.mk-choice-go { margin-top: auto; padding-top: .5rem; font-weight: 700; color: var(--mt-cyan-deep); }
@media (prefers-reduced-motion: reduce) { .mk-choice, .mk-choice:hover { transition: none; transform: none; } }
.mk-ticks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .2em;
  width: 1.2rem;
  height: 1.2rem;
  border-radius: 50%;
  background: var(--mt-cyan-deep) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l5 5L20 7'/%3E%3C/svg%3E") center / 60% no-repeat;
}

/* A band of figures. Facts about the product, never outcomes nobody measured. */
.mk-stat { font-size: clamp(2rem, 4vw, 3rem); font-weight: 800; letter-spacing: -.03em; line-height: 1; }
.mk-section.mk-ink .mk-stat { color: var(--mt-cyan); }
.mk-stat-label { font-size: .95rem; margin-top: .4rem; }

/* Small cards in a grid: a heading and two sentences of fact each. */
.mk-card {
  height: 100%;
  padding: 1.5rem;
  background: var(--card);
  border: 1px solid var(--mt-line);
  border-radius: var(--mt-radius-card);
}
.mk-card p { margin-bottom: 0; font-size: .95rem; }

/* The price, once, as one number. */
.mk-price-card {
  background: var(--card);
  border: 1px solid var(--mt-line);
  border-radius: var(--mt-radius-card);
  box-shadow: var(--mk-shadow);
  padding: clamp(1.5rem, 4vw, 2.5rem);
}
.mk-price { font-size: clamp(2.5rem, 6vw, 4rem); font-weight: 800; letter-spacing: -.04em; line-height: 1; }
.mk-price small { font-size: 1rem; font-weight: 600; letter-spacing: 0; color: var(--mk-ink-2); }

/* The pricing page, #213: the plans in a row, and the calculator beside its answer. */
.mk-plan { padding: clamp(1.25rem, 3vw, 1.75rem); }
.mk-plan .mk-price { font-size: clamp(2rem, 3.5vw, 2.75rem); }
.mk-plan .mk-price small { font-size: .85rem; }
.mk-plan-who { font-weight: 600; color: var(--mk-ink-2); font-size: .95rem; }
.mk-calc { display: grid; gap: 1rem; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.mk-calc-field { display: flex; flex-direction: column; gap: .35rem; }
.mk-calc-field > span { font-size: .8rem; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--mk-ink-2); }
.mk-calc-answer .mk-price { font-size: clamp(2.25rem, 5vw, 3.5rem); }
.mk-calc-table { font-size: .95rem; }
.mk-calc-table th { font-weight: 600; color: var(--mk-ink-2); border-top: 1px solid var(--mt-line); }

/* The closing band. */
.mk-cta {
  background: var(--mt-slate);
  color: #fff;
  border-radius: var(--mt-radius-card);
  padding: clamp(2rem, 5vw, 4rem);
  text-align: center;
}
/* Three classes deep, because `.mk .mk-h2` above is two and would otherwise win. */
.mk .mk-cta h2, .mk .mk-cta .mk-h2 { color: #fff; }
.mk .mk-cta p { color: rgba(255, 255, 255, .85); }

/* The call to open an account, at the top of a tool that works without one, KAN-309. The
   closing band's slate, made a strip: the line and the button side by side, wrapping to
   one above the other on a phone. */
.mk-signup { background: var(--mt-slate); color: #fff; padding: clamp(1rem, 2.5vw, 1.5rem) 0; }
.mk-signup-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem 2rem; }
.mk-signup-head { font-size: clamp(1.4rem, 3vw, 2rem); font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; margin: 0 0 .35rem; }
.mk-signup-line { color: rgba(255, 255, 255, .85); max-width: 40rem; margin: 0; }
.mk-signup-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.25rem; }
.mk-signup-signin { color: rgba(255, 255, 255, .85); text-decoration: underline; text-underline-offset: 3px; }
.mk-signup-signin:hover { color: #fff; }

/* A pill naming a language or a qualification. */
.mk-chip {
  display: inline-block;
  padding: .35rem .8rem;
  border: 1px solid var(--mt-line);
  border-radius: 999px;
  background: var(--card);
  font-size: .88rem;
  font-weight: 600;
  color: var(--mk-ink);
}

/* Buttons for the marketing pages: one filled, one quiet. **The shape is the button's**,
   KAN-98: `mk-btn` used to set its own padding, size and a 10px corner over `ui-btn`'s,
   so a marketing button and the app's were two sizes of the same thing. Now a page that
   wants the large one says `ui-btn-lg`, 44px, and `mk-btn` is only the hook for the depth
   and the lift below. */
.mk-btn-quiet { color: var(--mk-ink); border-color: var(--border); background-color: var(--background); }
.mk-btn-quiet:hover, .mk-btn-quiet:active { color: var(--mk-ink); border-color: #CBD2D9; background-color: var(--mt-off-white); }

/* The public bar, sticky with the page showing through it. Signed in, the bar is the
   ordinary one: an editor does not want a bar following it down. */
.ui-navbar.mk-nav {
  position: sticky;
  top: 0;
  z-index: 1030;
  background: rgba(255, 255, 255, .86);
  backdrop-filter: saturate(160%) blur(10px);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--mt-line);
}
.ui-navbar.mk-nav .ui-nav-link { color: var(--mk-ink-2); font-weight: 500; }
/* **Eight pages and the buttons on one row from 1280px**, below which they are the menu,
   `ui-navbar-expand-xl`: at the site's own 1rem and half-rem gutters they took two rows,
   and in French three. The signed-in bar's .92rem, and a little less room between. */
@media (min-width: 80rem) {
  .ui-navbar.mk-nav .ui-nav-link { font-size: .9rem; padding-inline: .45rem; }
}
/* And the bar's own measure is the widest step's from 75rem up: eight pages, Guest, Sign
   in and Start free beside the name need about 1,100px, which the 1,140px step leaves no
   room around. */
@media (min-width: 75rem) {
  .ui-navbar.mk-nav > .ui-container { max-width: 1320px; }
}
.ui-navbar.mk-nav .ui-nav-link.active, .ui-navbar.mk-nav .ui-nav-link:hover { color: var(--mk-ink); }
/* **The four things a visitor can do stay on one line**: the pages may wrap between
   themselves, but Start free alone on a second row reads as a stray button. */
@media (min-width: 80rem) {
  .ui-navbar.mk-nav #mainNav > .ms-auto { flex-wrap: nowrap; }
  .ui-navbar.mk-nav .mk-btn { white-space: nowrap; }
}

/* The footer's columns, for a visitor. */
.mk-footer-cols {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.5rem 2rem;
  text-align: left;
  margin-bottom: 2rem;
}
@media (min-width: 768px) { .mk-footer-cols { grid-template-columns: repeat(4, 1fr); } }
.mk-footer-cols h3 { font-size: .8rem; text-transform: uppercase; letter-spacing: .1em; color: rgba(255, 255, 255, .7); margin-bottom: .75rem; }
.mk-footer-cols ul { list-style: none; padding: 0; margin: 0; }
.mk-footer-cols li { margin-bottom: .4rem; }
.mk-footer-cols a { text-decoration: none; }
.mk-footer-cols a:hover { text-decoration: underline; }

/* Hover lift on the cards, and none of it for anybody who asked for less motion. */
.mk-card, .mk-window { transition: transform .25s ease, box-shadow .25s ease; }
.mk-card:hover { transform: translateY(-2px); box-shadow: 0 10px 24px -14px rgba(27, 36, 48, .25); }
@media (prefers-reduced-motion: reduce) {
  .mk-card, .mk-window { transition: none; }
  .mk-card:hover { transform: none; }
}

/* A page's head, for the pages that are a tool or a list rather than a pitch: the
   playground, the resources, the manual, the contact form. Quieter than the hero, one
   idea and no picture, so the thing the page is for starts within the first screen. */
.mk-head { padding: clamp(2rem, 5vw, 3.5rem) 0 clamp(1.25rem, 3vw, 2rem); }
.mk-head h1 { font-size: clamp(2rem, 4vw, 3rem); font-weight: 800; letter-spacing: -0.03em; line-height: 1.05; }
.mk-head .mk-lead { max-width: 44rem; }

/* A chip that is a link: the playground's languages. The current one is filled. */
a.mk-chip { text-decoration: none; transition: border-color .15s ease, background-color .15s ease; }
a.mk-chip:hover { border-color: var(--mt-cyan-deep); color: var(--mt-cyan-deep); }
a.mk-chip.active, a.mk-chip[aria-current] { background: var(--mt-cyan-deep); border-color: var(--mt-cyan-deep); color: #fff; }
.mk-chips { display: flex; flex-wrap: wrap; gap: .5rem; }

/* A card that is a link, whole. */
a.mk-card { display: flex; flex-direction: column; color: inherit; text-decoration: none; }
a.mk-card:hover { border-color: #CBD2D9; }
a.mk-card .mk-card-cta { margin-top: auto; padding-top: 1rem; color: var(--mt-cyan-deep); font-weight: 600; }
a.mk-card:hover .mk-card-cta { text-decoration: underline; }

/* The manual's index: a group heading and its topics as cards. */
.mk-topic h3 { font-size: 1rem; font-weight: 700; margin-bottom: .35rem; }
.mk-topic p { font-size: .92rem; }

/* A form on the marketing side: the same card, roomier fields. */
.mk-form .ui-input { padding: .7rem .9rem; border-radius: var(--mt-radius); border-color: var(--mt-line); }
.mk-form .ui-label { font-weight: 600; color: var(--mk-ink); }

/* The playground's editor and the deploy page sit on the tint, edge to edge. */
.mk-tool { background: var(--mt-off-white); padding: 1.5rem 0 3rem; }

/* A card that sizes to its words rather than to its column: two stacked beside a form. */
.mk-card.mk-card-auto { height: auto; }

/* The one-time colours notice, #157: a strip and not an alert. */
.scheme-notice { background: #FFF8E6; border-bottom: 1px solid #F1E2B8; color: var(--mt-slate); }
.scheme-notice a { color: var(--mt-cyan-darker); }

/* ---------------------------------------------------------------------------
   Keyboard baseline, #132.
   --------------------------------------------------------------------------- */

/* The skip link: off-screen until it has focus, then the first thing on the page. */
.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  z-index: 2000;
  padding: .6rem 1rem;
  background: var(--mt-slate);
  color: #fff;
  border-radius: 0 0 8px 0;
  text-decoration: none;
}
.skip-link:focus { left: 0; outline: 3px solid var(--mt-gold); outline-offset: 0; }
main:focus { outline: none; }

/* **The one focus ring is `apps/web/src/styles.css`'s**, KAN-98, unlayered there so no
   component or utility can quietly replace it. It was spelt here as well, in this layer,
   where it lost to that copy on every page and differed from it under a colour scheme. */

/* A submit button that has been pressed, #142: kept its words, greyed, and a small
   spinner after them, until the next page arrives. `busy.js` sets the class. */
.ui-btn.is-busy { opacity: .7; pointer-events: none; }
.ui-btn.is-busy::after {
  content: "";
  display: inline-block;
  width: .9em;
  height: .9em;
  margin-left: .5em;
  vertical-align: -0.1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: mt-spin .75s linear infinite;
}
@keyframes mt-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .ui-btn.is-busy::after { animation: none; } }

/* ---------------------------------------------------------------------------
   Brand presence and motion on the marketing pages, #222 and #217.
   --------------------------------------------------------------------------- */

/* A quiet wash of the emblem's cyan behind the hero and every page head, with a warmer
   note of the gold opposite it: colour the reader feels rather than reads, since
   neither may carry words. The page is still white where the words are. */
.mk-hero, .mk-head {
  background:
    radial-gradient(900px 420px at 88% -12%, rgba(35, 173, 227, .16), transparent 62%),
    radial-gradient(700px 320px at -6% -20%, rgba(214, 156, 40, .10), transparent 60%);
}

/* The eyebrow gets the gold as the rule it was meant to be. */
/* Flex and not inline-flex, so an eyebrow keeps its own line and a centred one stays
   centred. */
.mk-eyebrow { display: flex; align-items: center; gap: .55rem; }
.mk-eyebrow::before {
  content: "";
  width: 1.25rem;
  height: 2px;
  border-radius: 2px;
  background: var(--mt-gold);
}
.text-center .mk-eyebrow, .mk-eyebrow.text-center, .text-center > .mk-eyebrow { justify-content: center; }

/* The closing band in the brand rather than a flat slate: the slate deepening into the
   dark cyan. White on the lightest point of it measures above 6:1. */
.mk-cta {
  background:
    radial-gradient(600px 260px at 100% 0%, rgba(35, 173, 227, .28), transparent 65%),
    linear-gradient(135deg, var(--mt-slate) 0%, #1E4E63 100%);
}

/* The primary button with a little depth, and a lift on hover, the way the products
   this is compared with draw theirs. */
.mk-btn.ui-btn-primary {
  box-shadow: 0 1px 0 rgba(255, 255, 255, .18) inset, 0 6px 16px -8px rgba(21, 118, 156, .7);
  transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.mk-btn.ui-btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .18) inset, 0 10px 22px -10px rgba(21, 118, 156, .8);
}

/* **No icon on a secondary button on the marketing pages.** Every button in the app
   carries one, which is right where a button sits among controls; on a page that sells,
   the icon is decoration beside a call to action and the pages this is measured against
   use them sparingly. The primary keeps its icon, being the one thing to press. */
.mk .mk-btn-quiet .ui-btn-icon,
.mk .ui-btn-outline-light .ui-btn-icon,
.mk .ui-btn-outline .ui-btn-icon { display: none; }

/* The product in its window lifts a little under the pointer. */
.mk-window:hover { transform: translateY(-3px); box-shadow: 0 32px 70px -28px rgba(27, 36, 48, .42), 0 12px 28px -16px rgba(27, 36, 48, .25); }

/* A field a tick governs, while the tick is off, KAN-100. Dimmed rather than disabled:
   a disabled field is left out of the form data, and this one still has to carry its
   number so turning the setting back on does not lose it. */
.is-idle { opacity: .55; }

/* **A section's own column**, KAN-60: the narrower measure a block of questions or a long
   run of prose is set in, centred in the section. It was `style={{ maxWidth: '52rem' }}`
   on three pages, which is a width the system could not see and nobody would find when
   the scale changed. Wider than `.mk-measure`, which is a reading measure for one
   paragraph; this is a column that holds a list or a form. */
.mk-column { max-width: 52rem; margin-inline: auto; }

/* The second ink, for words that sit beside a heading rather than under it: a caption, a
   list of details. `.mk p` already gets it; this is for the elements that are not `p`. */
.mk-soft { color: var(--mk-ink-2); }

/* **A list of questions and their answers**, KAN-60. The markup is a `<dl>` because that
   is what it is, and the spacing is the scale's rather than a Bootstrap margin picked per
   page: the two FAQ blocks on the site had different gaps between an answer and the next
   question, which is the drift this system exists to stop. Printed rather than folded
   away: content behind a click is content an answer engine may not read. */
.mk-faq { margin-bottom: 0; }
.mk-faq > div + div { margin-top: var(--mk-space-8); }
.mk-faq dt { margin-bottom: var(--mk-space-2); }
.mk-faq dd { margin-bottom: 0; }
.mk-faq dd p:last-child { margin-bottom: 0; }

/* The reveal: added by `reveal.js`, and only to what is below the first screen. */
.mk-reveal { opacity: 0; transform: translateY(14px); transition: opacity .5s ease, transform .5s cubic-bezier(.2, .7, .2, 1); }
.mk-reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .mk-btn.ui-btn-primary, .mk-btn.ui-btn-primary:hover, .mk-window:hover { transition: none; transform: none; }
  .mk-reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------------------------------------------------------------------------
   The signed-in bars, #222: an app header rather than two rows of links.
   --------------------------------------------------------------------------- */
.ui-navbar.mt-appbar { background: var(--background); padding-top: .5rem; padding-bottom: .5rem; }

/**
 * **This row stays in view, and the brand row above it does not.** KAN-277.
 *
 * It carries the pages, Ask AI, the Presented mount, the reader's name and Sign out, and
 * none of those is any use on the half of the site that scrolls: an editor, a builder, a
 * long module page. Ask AI scrolling away is what sent it into eight editors' own control
 * strips, KAN-43, and the Presented banner exists to reach a student wherever they are,
 * KAN-137, which it could not do once they had scrolled past it.
 *
 * **One row and not two.** The brand bar above is a logo and nothing to press, so it
 * scrolls off and this one lands against the top: two pinned rows is a permanent bite out
 * of a laptop screen for the sake of a wordmark. `mk-nav`, the signed-out bar, has been
 * sticky all along and shares this `z-index`, which is Bootstrap's own for a fixed navbar.
 *
 * **Opaque rather than `mk-nav`'s blur**, deliberately: this one scrolls over Monaco and
 * over a grid of cells, where a translucent bar reads as a rendering fault rather than as
 * depth.
 */
.ui-navbar.mt-appnav {
  position: sticky;
  top: 0;
  z-index: 1030;
  background: var(--background);
  border-top: 1px solid #EDF1F4;
  border-bottom: 1px solid var(--mt-line);
  box-shadow: 0 1px 2px rgba(27, 36, 48, .03);
}

/**
 * **Anything linked to by an anchor clears the pinned bar.** KAN-277.
 *
 * `/terms` links at its parts, a lesson's outline links at its blocks, and the browser
 * scrolls a target to the very top of the viewport, which is now under the bar. Set once
 * here rather than on each of them: the bar is a fact about every page, so the allowance
 * for it belongs with the bar and not with whatever happens to be linked at this week.
 *
 * **Generous rather than exact, and measured rather than guessed.** The bar is not one
 * row: the bands wrap, so at 1162px it stands 132px for a sysadmin with four of them and
 * 90px for a teacher with two, and it grows again with the reader's own text size,
 * `readingtext.ts`. 9rem clears the tallest of those with room to spare, and landing a
 * heading a little low is a great deal better than landing it behind something.
 */
:target { scroll-margin-top: 9rem; }

/**
 * **The tools and the account, told apart by a rule rather than by spacing.** KAN-277.
 *
 * Ask AI sits at the end of the pages and the account menu after it, and without a line
 * between them the button reads as one more thing about the reader rather than as
 * something to press. The same separator the bands already use between themselves,
 * `.mt-navband + .mt-navband`, so the bar has one idea of what a divider is.
 *
 * **It goes on the account side**, which is what makes Ask AI the last of the tools
 * rather than the first of the furniture.
 */
.mt-barmine { border-left: 1px solid var(--mt-line); padding-left: .75rem; }

/* The tools keep the bar's own text size rather than the `small` the account cluster
   carries: a control to press is not a footnote about who is signed in. */
.mt-bartools .ui-btn { font-size: .92rem; }
/* Each item a soft pill: grey under the pointer, tinted cyan where the reader is, so
   the current page is said by a shape and a colour and a weight together, #132. */
.ui-navbar.mt-appnav .ui-nav-link {
  padding: .4rem .7rem;
  margin: .1rem .05rem;
  border-radius: .5rem;
  color: var(--mt-ink-2);
  font-weight: 500;
  font-size: .92rem;
  transition: background-color .12s ease, color .12s ease;
}
.ui-navbar.mt-appnav .ui-nav-link:hover { background: var(--muted); color: var(--mt-ink); }
.ui-navbar.mt-appnav .ui-nav-link.active {
  background: #E6F1F6;
  color: var(--mt-cyan-darker);
  font-weight: 600;
}
@media (prefers-reduced-motion: reduce) { .ui-navbar.mt-appnav .ui-nav-link { transition: none; } }

/* **The bar's bands, KAN-90.** Each group is its own flex row with a quiet label in front
   of it, and the rows sit side by side on a wide screen and stack on a phone, where the
   whole bar is already behind the toggle. The label is small, upper case and grey: it has
   to be readable as a heading and never mistaken for a link, so it carries no underline,
   no hover and a weight below the items'. */
.ui-navbar.mt-appnav .ui-navbar-collapse { display: flex; flex-wrap: wrap; gap: .25rem 1.1rem; }
.mt-navband { display: flex; align-items: center; gap: .35rem; }
.mt-navband + .mt-navband { border-left: 1px solid var(--mt-line); padding-left: 1.1rem; }
.mt-navband-label {
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  /* **Solid, not faded.** `--mt-ink-2` measures 7.4:1 on the bar's white and 3.7:1 at the
     .72 this carried, which the axe run in the browser suite failed it for: small upper-case
     words are exactly the ones a fade makes unreadable, KAN-92. The heading is quieter than
     the items by its size and weight instead. */
  color: var(--mt-ink-2);
  white-space: nowrap;
}
.mt-navband .ui-navbar-nav { flex-direction: row; flex-wrap: wrap; }
/* On a phone each band is its own line, with its label above it rather than beside it:
   side by side, four labels and their items wrap into an unreadable ribbon. */
@media (max-width: 991.98px) {
  .ui-navbar.mt-appnav .ui-navbar-collapse { flex-direction: column; align-items: stretch; }
  /* **Shut until the menu button opens it**, KAN-106. The `display: flex` above is more
     specific than Bootstrap's `.collapse:not(.show)`, so on a phone the whole bar was
     always open, filling the first screen with seventeen links, and the button toggled a
     class nothing could see. */
  .ui-navbar.mt-appnav .ui-navbar-collapse:not(.show) { display: none; }
  .mt-navband { flex-direction: column; align-items: flex-start; gap: .1rem; }
  .mt-navband + .mt-navband {
    border-left: 0;
    border-top: 1px solid var(--mt-line);
    padding-left: 0;
    padding-top: .4rem;
    margin-top: .3rem;
  }
}

/* ---------------------------------------------------------------------------
   The footer at the foot of the window, and the sign-in pages filling it, #222.

   A short page (sign in, choose, reset a password) ended its grey band half way down
   and left the rest of the window white above a footer that floated in the middle.
   The page is a column now, `main` takes the space left over, and a page whose whole
   content is one tinted band lets that band fill it, with the brand's wash behind the
   card the way the marketing pages have it.
   --------------------------------------------------------------------------- */
body { min-height: 100vh; display: flex; flex-direction: column; }
body > main { flex: 1 0 auto; display: flex; flex-direction: column; }
/* `:first-child` and not `:only-child`: React puts a page's own `<link>` after it. The
   page is a sign-in screen when that band is the only section, so nothing follows it. */
body > main > section.bg-muted:first-child:not(:has(~ section, ~ div, ~ header)) { flex: 1 0 auto; }
/* In `:where`, so it weighs nothing: a reader's own colour scheme, `lib/scheme.ts`, sets
   `.bg-muted` too and must win over the wash. */
:where(body > main > section.bg-muted:first-child:not(:has(~ section, ~ div, ~ header))) {
  background:
    radial-gradient(800px 380px at 50% -10%, rgba(35, 173, 227, .12), transparent 65%),
    var(--mt-surface) !important;
}

/* ---------------------------------------------------------------------------
   Phones, #220.

   Bootstrap's `g-5` is a 3rem gutter, and a row pulls itself out by half of it on
   each side, which is more than the container's own padding at phone width: every
   marketing section built on one pushed the page 12px past the screen and gave it a
   sideways scroll. Below `md` the gutter is the ordinary one. The calculator's two
   fields go one above the other, the price cards breathe less, and the hero's
   headline steps down so four words fit a line.
   --------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
  .mk .ui-row.ui-g-5, .mk .ui-row.ui-gx-5 { --gx: 1.5rem; }
  .mk .ui-row.ui-g-5 { --gy: 2rem; }
  .mk-calc { grid-template-columns: 1fr; }
  .mk-plan, .mk-price-card { padding: 1.25rem; }
  .mk-cta { padding: 2rem 1.25rem; }
  .mk-display { font-size: clamp(2.1rem, 9vw, 2.6rem); }
  .mk-strip ul { gap: .5rem 1.25rem; font-size: .85rem; }
  .mk-calc-table { font-size: .85rem; }
  /* A long call to action wraps rather than widening the page on a 320px screen. */
  .mk-btn { white-space: normal; max-width: 100%; }
}

/* ---------------------------------------------------------------------------
   The booking flow's head on the light design system, #222.
   --------------------------------------------------------------------------- */
.mk-book-head { padding-bottom: clamp(1.5rem, 3vw, 2.25rem); border-bottom: 1px solid var(--mt-line); }
.mk-book-head h1 { color: var(--mk-ink); }
.mk-book-head .mk-lead { color: var(--mk-ink-2); }
.mk-book-head .book-steps { margin-top: 1.5rem; font-size: .85rem; color: var(--mk-ink-2); }
.mk-book-head .book-steps li { opacity: 1; }
.mk-book-head .book-steps li.is-now { color: var(--mk-ink); }
.mk-book-head .book-steps .step-dot { border-color: var(--mt-line); background: var(--card); color: var(--mk-ink-2); }
.mk-book-head .book-steps li.is-now .step-dot,
.mk-book-head .book-steps li.is-done .step-dot {
  background-color: var(--mt-cyan-deep);
  border-color: var(--mt-cyan-deep);
  color: #fff;
}
.mk-book-head .trust-strip { margin-top: 1rem; }

/* The account banner on /resources, its topics and every lab's manual page, KAN-502: two
   messages and two buttons, large enough to be the first thing read. Tokens only, so the
   dark theme and a reader's own scheme restyle it; the buttons are the platform's own. */
.mk-account-banner {
  margin: 0 auto 1.5rem;
  padding: clamp(1.25rem, 3vw, 2rem);
  background: var(--card);
  color: var(--card-foreground, var(--mk-ink));
  border: 2px solid var(--mt-primary);
  border-radius: var(--mt-radius-card);
}
.mk-account-banner h2 { font-size: clamp(1.35rem, 3vw, 1.9rem); margin: 0 0 .75rem; color: inherit; }
.mk-account-banner p { font-size: clamp(1rem, 1.6vw, 1.15rem); line-height: 1.5; margin: 0 0 .75rem; color: inherit; max-width: 46rem; }
.mk-account-banner .mk-account-banner-actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1rem; }
.mk-account-banner .mk-account-banner-actions a { flex: 1 1 14rem; text-align: center; justify-content: center; }

} /* @layer brand */
