/* ============================================================
   Marketing pages (/welcome, /pricing) — static SSR, anonymous.
   Consumes the app's design tokens (app.css :root) so the pages
   are unmistakably the same product, but with an airier rhythm:
   marketing breathes, the app is dense. Light theme only — the
   dark theme is a signed-in, per-circuit override.
   Everything scopes under .marketing-shell.
   ============================================================ */

.marketing-shell {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--color-bg);
    color: var(--color-text);
    font-size: 15px;
    line-height: 1.55;
}

/* Borderless chrome elsewhere makes visible focus mandatory (house rule). */
.marketing-shell a:focus-visible,
.marketing-shell button:focus-visible,
.marketing-shell input:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 1px;
}

/* ---- Header / footer ---- */
.mk-header {
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 24px;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border-strong);
}

/* The logo (2026-10-06), as the design canvas draws it in this header: a 24px
   symbol, a 10px gap and the name at 15px, all in the logo's teal. The symbol
   and the name's face come from app.css (LogoSymbol, .logo-name and the --logo-*
   tokens), which these pages read and never redefine. */
.mk-brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: var(--logo-ink);
    text-decoration: none;
}

.mk-brand .logo-symbol {
    width: 24px;
    height: 24px;
}

.mk-brand .logo-name {
    font-size: 15px;
}

.mk-nav {
    display: flex;
    align-items: center;
    gap: 6px;
}

.mk-nav a {
    padding: 6px 10px;
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text);
    text-decoration: none;
}

.mk-nav a:hover {
    background: var(--color-field);
}

.mk-nav .mk-signin {
    border: 1px solid var(--color-accent);
    color: var(--color-accent);
}

.mk-main {
    flex: 1;
}

.mk-footer {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 8px 16px;
    padding: 18px 24px;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: 13px;
}

.mk-footer a {
    color: var(--color-text-muted);
}

.mk-foot-sep {
    margin: 0 6px;
}

/* The footer's sign-off opens with the symbol on its own, at 16px. */
.mk-foot-product {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.mk-foot-product .logo-symbol {
    width: 16px;
    height: 16px;
}

/* ---- Shared section furniture ---- */
.mk-inner {
    max-width: 1060px;
    margin: 0 auto;
    padding: 0 24px;
}

.mk-hero {
    padding: 56px 0 48px;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
}

.mk-hero-slim {
    padding: 40px 0 32px;
}

/* ---- Dark hero (landing): almost no words, the product shot carrying it.
   Uses the app's DARK-theme values so the mock reads as a real screenshot. ---- */
.mk-hero-dark {
    position: relative;
    background: #131417;
    color: #ffffff;
    overflow: hidden;
}

/* The photograph bleeds to the hero's top, bottom and right edges; the copy
   sits on the dark left, which the gradient dissolves the image into. */
/* Starts right of where the headline ends — white copy must never land on the
   bright screen in the photograph. */
.hero-photo {
    position: absolute;
    inset: 0 0 0 42%;
}

.hero-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* Crops from the image's left, so the monitor lands clear of the gradient
       rather than being veiled by it. */
    object-position: 34% center;
    display: block;
}

/* The dissolve has to clear the screen: it is opaque only over the copy, and
   fully transparent well before the monitor starts. */
.hero-photo::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to right,
        #131417 0%,
        rgba(19, 20, 23, 0.85) 6%,
        rgba(19, 20, 23, 0.35) 16%,
        rgba(19, 20, 23, 0) 30%);
}

/* ---- Hero carousel (2026-08-03): the photograph's alternative, chosen on
   /marketing-settings. Nothing is cropped: a photograph can be cropped anywhere,
   while cropping a screenshot of the grid cuts off the rows and columns that are
   the whole point of showing it. No gradient for the same reason — a dissolve
   over the left edge would veil the employee-name column.

   The hero becomes a two-column GRID in this mode (see .mk-hero-carousel below)
   so the section's height follows the screenshot. The photograph's absolute
   positioning cannot: it pins the shot inside a hero sized by the copy, so past
   about 1740px of window the box grew wider without growing taller and the
   picture stopped getting any bigger — at 3440px it drew at half the width it
   had, framed in black. ---- */
.hero-carousel {
    display: flex;
    flex-direction: column;
    padding: 36px 16px 24px 8px;
    /* No touch-action restriction here, deliberately (2026-08-03). `pan-y` claimed
       sideways gestures for the swipe, and took pinch to zoom with it — and even
       `pan-y pinch-zoom` would let you zoom in and then be unable to drag around
       what you had zoomed into, which is the whole reason for zooming. The browser
       keeps every gesture; the script simply reads a horizontal drag off touchend,
       and stands down while the page is pinched (see hero-carousel.js). There is
       no horizontal overflow at normal zoom, so the browser does nothing with the
       gesture we act on. */
}

/* Grid rather than absolute stacking: every slide sits in the one cell, so the
   box is exactly as tall as its tallest image and no height has to be guessed.
   Slides of one shape therefore letterbox not at all; an odd one out only makes
   the box as tall as itself and leaves the others centred in it. */
.hero-slides,
.hero-captions {
    display: grid;
    justify-items: center;
}

/* Slides sit on the FLOOR of the box (2026-08-03), not its middle. The box is as
   tall as the tallest slide, so a shorter one used to float with the empty space
   split above and below it — and the caption, which is outside the box, stayed
   put. The gap between picture and caption therefore changed from slide to slide,
   which reads as the caption drifting away. Bottom-aligned, that gap is identical
   for every slide and all the slack collects above, where it is just more hero. */
.hero-slides {
    align-items: end;
}

.hero-captions {
    align-items: center;
}

.hero-slide,
.hero-caption {
    grid-area: 1 / 1;
}

/* Only the current one is opaque. A crossfade carries no movement, so this is the
   reduced-motion-safe cue rather than the kind that setting removes (the roster's
   remote-change fade takes the same view). 700ms since 2026-10-14 (Robert: "dissolve
   a little slower"; it was 260ms), for the clicks as well as the timer, so the two
   cannot look different. Both slides are half visible in the middle of it, which at
   this length reads as a dissolve rather than a cut. */
.hero-slide,
.hero-caption {
    opacity: 0;
    visibility: hidden;
    transition: opacity 700ms ease, visibility 0s linear 700ms;
}

.hero-slide.is-current,
.hero-caption.is-current {
    opacity: 1;
    visibility: visible;
    transition: opacity 700ms ease, visibility 0s;
}

/* The <picture> wrapper exists only to offer a phone a different file; it must not
   become a box of its own, or the image would stop being a direct child for the
   grid stacking. */
.hero-slide picture {
    display: contents;
}

/* max-width without width: fill the column, but never scale a screenshot PAST its
   own pixels, which would only make it soft. So shoot slides at least as wide as
   the column gets — around 1900px — or they will sit smaller than the space. */
.hero-slide img {
    max-width: 100%;
    height: auto;
    display: block;
}

/* The caption, real text in the page. SINCE 2026-10-13 A SLIDE CARRIES ITS WORDS IN THE
   PICTURE (Robert: the text under each slide goes, the words and the pointers go into
   the slide, in the demo video's look; docs/marketing-slides draws them), on a phone too
   since later the same day (a phone gets a crop of the slide with the words placed
   inside it), so the caption is hidden from sight at every width rather than shown
   under the picture. It stays in the page: a screen reader hears exactly what it heard
   before, which is the 2026-08-03 reason for real text that still holds. The hiding
   rule is just below; the sizes here matter only if it is ever shown again. */
.hero-caption {
    margin: 14px 0 0;
    text-align: center;
    font-size: 18px;
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.82);
}

/* The caption stack is visually hidden with the standard clip, never display: none, which
   would take the words out of the accessibility tree and silence the live region.
   Absolute, so it takes no room: the controls sit under the picture by their own margin
   alone. At every width since later on 2026-10-13; it sat inside a min-width: 561px
   query for the few hours a phone still showed the caption under the old picture. */
.hero-captions {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Three columns, the middle one the arrows and dots and the right one the pause button
   (2026-10-14), so adding the button moves nothing: the arrows and dots stay centred
   under the picture. The button sits right next to the next arrow, at the same 14px gap
   the arrows and dots keep between themselves (Robert, 2026-10-14; it was 56px apart on
   a big screen and 24px on a phone, which read as a separate control). */
.hero-controls {
    flex: none;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    margin-top: 18px;
}

.hero-nav {
    grid-column: 2;
    display: flex;
    align-items: center;
    gap: 14px;
}

.hero-pause {
    grid-column: 3;
    justify-self: start;
    margin-left: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.hero-pause .hero-play-icon,
.hero-pause.is-paused .hero-pause-icon {
    display: none;
}

.hero-pause.is-paused .hero-play-icon {
    display: block;
}

/* The script renders the controls and only then unhides them, so a visitor with
   JavaScript off gets the first slide instead of buttons that do nothing. The
   display rule above would beat the plain `hidden` attribute without this. */
.hero-controls[hidden] {
    display: none;
}

/* Ghost buttons, the app's own control chrome: transparent until hovered. */
.hero-arrow {
    width: 32px;
    height: 32px;
    padding: 0;
    background: none;
    border: 1px solid rgba(255, 255, 255, 0.28);
    color: #ffffff;
    font-family: inherit;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
}

.hero-arrow:hover {
    background: rgba(255, 255, 255, 0.14);
    border-color: rgba(255, 255, 255, 0.55);
}

.hero-arrow:focus-visible,
.hero-dot:focus-visible {
    outline: 2px solid #71c0d9;
    outline-offset: 2px;
}

.hero-dots {
    display: flex;
    gap: 8px;
}

/* Square, like everything else in the app — no rounded corners. */
.hero-dot {
    width: 9px;
    height: 9px;
    padding: 0;
    background: rgba(255, 255, 255, 0.3);
    border: none;
    cursor: pointer;
}

.hero-dot.is-current {
    background: #71c0d9;
}

/* Carousel mode only: both columns are in flow, so the hero is as tall as the
   taller of them and a wide window makes the screenshot BIGGER instead of just
   adding black around it. The 42% first column keeps the copy exactly where the
   photograph's arrangement put it. The photograph itself stays absolute — it is
   cropped to fill, so it has no height of its own to contribute, and there is
   nothing to be gained by letting it drive the section. */
.mk-hero-dark.mk-hero-carousel {
    display: grid;
    grid-template-columns: 42% 1fr;
    align-items: center;
}

/* Left-anchored, and the column is capped in vw as well as px so the copy
   still ends left of the photograph (which starts at 42%) at every width down
   to the stacking breakpoint — a fixed px cap overlaps it on narrow desktops. */
.hero-split {
    position: relative;   /* above the photo layer */
    z-index: 1;
    display: grid;
    grid-template-columns: minmax(0, min(460px, 34vw));
    align-items: center;
    min-height: 480px;
    padding: 56px 24px 56px clamp(24px, 5vw, 96px);
}

/* The hero kicker: quiet, but first-read because it shares the hero's one
   colour with nothing but the Try it out button. Sized to stay on ONE line — a
   wrapped kicker reads as a sentence, which is not what this element is. */
.hero-label {
    margin: 0 0 14px;
    color: #71c0d9;          /* the app's info-strip cyan — our one signature colour */
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.08em;   /* sized so 41 characters clear the 340px column at 1000px */
    text-transform: uppercase;
}

/* The headline is sized to the copy column rather than fixed (Robert,
   2026-09-22, choosing a smaller headline over three lines). The column is
   min(460px, 34vw), and the longer half of the current headline, "breaks the
   rules by accident.", is 12.8px wide per px of font size, so 2.6vw keeps it
   on one line while the column is a fraction of the window and 35px keeps it
   on one line once the column has reached its 460px cap (36px is one pixel
   too wide there). Measured at seven widths from 1000px to 1920px, not
   computed. The 42px the page had until this date could not fit two lines
   below about 1600px, because the column is bounded by where the screenshots
   start; a longer headline needs re-measuring, and the phone sizes below
   still override this one. */
.mk-hero-dark h1 {
    margin: 0 0 16px;
    font-size: min(35px, 2.6vw);
    line-height: 1.1;
    letter-spacing: -0.015em;
    color: #ffffff;
}

/* The headline's two halves, each its own line at every width. */
.mk-hero-dark h1 span {
    display: block;
}

.hero-lines {
    display: grid;
    gap: 6px;
}

.hero-line {
    margin: 0;
    font-size: 19px;
    color: rgba(255, 255, 255, 0.72);
}

/* Holds whichever action the visitor gets — the two buttons, or the signed-in
   text link — so the spacing below the claim lines is set in one place. Centred
   on the row, because the two buttons are different heights. */
.hero-actions {
    margin-top: 26px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
}

/* The hero's button row is rendered twice (LandingPage.razor says why): above the
   pictures everywhere but a phone, below them on a phone (the 560px block below). */
.hero-actions-below {
    display: none;
}

/* Try it out, the hero's loud button (Robert, 2026-09-24: "a lot more visible").
   The hero's own cyan (#71c0d9, the info strip's, the same colour the kicker
   wears and the only colour on the hero) with the strip's own dark ink, which
   is the one ink recorded as readable on it; white fails contrast on this cyan.
   Bigger type and more padding than any other marketing button, so it reads as
   the thing to click before the text is read. It is on the dark hero only, so
   the rule is scoped to it. Two lines: the name, and under it the one fact a
   visitor needs before clicking, that no sign-up and no email address is asked
   for (Robert, 2026-09-24, folded into the button rather than sitting under it).
   A column flex so the two spans stack and centre; inline-flex outranks
   .mk-btn's inline-block because this selector carries two classes. */
.mk-hero-dark .mk-btn-try {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 12px 28px 11px;
    line-height: 1.2;
    background: #71c0d9;
    color: #16323b;
    border-color: #71c0d9;
}

.mk-hero-dark .mk-btn-try:hover {
    filter: brightness(1.1);
}

.mk-btn-try-title {
    font-size: 18px;
    font-weight: 700;
}

/* The second line: smaller and a shade lighter than the name, so the name is
   still what the eye lands on, but the same dark ink family so it stays readable
   on the cyan (a white or grey would fail contrast there). */
.mk-btn-try-sub {
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: 0.01em;
    color: rgba(22, 50, 59, 0.82);
    white-space: nowrap;
}

/* " on a laptop or tablet", the end of the button's name below 820 pixels only
   (2026-10-06, " on a laptop" below 1024 until 2026-10-07; see the small-screen
   block below). Hidden rather than absent, so a screen reader
   hears exactly what is shown at each width. */
.mk-btn-try-laptop {
    display: none;
}

/* Get in touch, the outlined button beside it, sits on the dark hero, where the
   ghost button's text-colour token is dark on dark: white ink and a white
   hairline here. A size up from the ordinary ghost button (Robert asked on
   2026-09-24 whether it needed changing beside the two-line Try it out): the
   outline is still the right shape for the second choice, but at 14px and 10px
   of padding it read as an afterthought next to a 62px neighbour, so it is 15px
   with a little more padding, which is enough for the pair to read as a pair
   without the two competing. */
.mk-hero-dark .mk-btn-ghost {
    padding: 13px 24px;
    font-size: 15px;
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.55);
}

.mk-hero-dark .mk-btn-ghost:hover {
    background: rgba(255, 255, 255, 0.12);
}

/* Try it out was hidden below 1024 pixels here until 2026-10-06. It shows at every
   width now, and below 820 it says it needs a laptop or tablet and opens the panel
   further down this file (Robert, 2026-10-06 and 2026-10-07). */

/* ---- The demo video, shown in place of the hero's pictures below 820 pixels when a
   System Admin chooses it on /marketing-settings (Robert, 2026-10-07; off by default).
   The page renders it only then, and marks the section mk-hero-video-small; the
   small-screen block below swaps it in. Centred on a small tablet at a width that keeps
   the whole frame inside the window (68vh wide is about 64vh tall); edge to edge on a
   phone, the carousel's own rule for screenshots. The frame is 1080 by 1024, the
   LinkedIn video's 4:5 frame with its empty top and bottom bands and the website's
   address cut away (2026-10-08), since a visitor here is already on the website. ---- */
.hero-video {
    display: none;
    text-align: center;
}

.hero-video video {
    display: block;
    width: min(100%, 440px, 68vh);
    height: auto;
    aspect-ratio: 1080 / 1024;
    margin: 0 auto;
    background: #000000;
}

/* How long it is and that it has no sound, the two things a phone visitor wants to
   know before pressing play in a public place. */
.hero-video-note {
    margin: 10px 0 0;
    font-size: 13px;
    color: rgba(255, 255, 255, 0.62);
}

/* The <picture> around the photograph only spares a small screen the download when the
   video stands in; it must not become a box, or the image's 100% height would be a
   share of an inline element's. */
.hero-photo picture {
    display: contents;
}

/* The signed-in route back to work: a text link, not a button. The button is the
   prospect's call to action and isn't spent on someone who already has an
   account. Cyan because that is the hero's one accent (see .hero-label). */
.hero-link {
    color: #71c0d9;
    font-size: 17px;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.hero-link:hover {
    color: #ffffff;
}

/* ---- The one big statement (the Avid pattern: a single centred paragraph) ---- */
.mk-statement {
    padding: 56px 0;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    text-align: center;
}

.mk-statement p {
    max-width: 860px;
    margin: 0 auto;
    font-size: 24px;
    line-height: 1.45;
}

.mk-kicker {
    margin: 0;
    color: var(--color-accent);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.mk-hero h1 {
    margin: 10px 0 14px;
    font-size: 34px;
    line-height: 1.15;
    letter-spacing: -0.01em;
}

.mk-lede {
    max-width: 660px;
    margin: 0;
    font-size: 17px;
    color: var(--color-text-muted);
}

.mk-btn {
    display: inline-block;
    padding: 10px 18px;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    border: 1px solid transparent;
}

.mk-btn-primary {
    background: var(--color-accent);
    color: #ffffff;
}

.mk-btn-primary:hover {
    filter: brightness(1.1);
}

.mk-btn-ghost {
    border-color: var(--color-border-strong);
    color: var(--color-text);
}

.mk-btn-ghost:hover {
    background: var(--color-field);
}

.mk-section {
    padding: 48px 0;
}

.mk-section-alt {
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    border-bottom: 1px solid var(--color-border);
}

.mk-section h2,
.mk-card h2,
.price-notes h2 {
    margin: 0 0 8px;
    font-size: 24px;
    line-height: 1.2;
}

.mk-sub {
    max-width: 680px;
    margin: 0 0 24px;
    color: var(--color-text-muted);
}

.mk-footnote {
    margin: 18px 0 0;
    font-size: 13px;
    color: var(--color-text-muted);
}

.mk-list {
    max-width: 760px;
    margin: 16px 0 0;
    padding-left: 20px;
}

.mk-list li {
    margin-bottom: 10px;
}

.mk-small {
    font-size: 13px;
    color: var(--color-text-muted);
}

/* ---- The five points: a numbered list, built to be skimmed. The counter
   markers are drawn rather than list-style so they can carry the accent. ---- */
.point-list {
    counter-reset: point;
    max-width: 820px;
    margin: 20px 0 0;
    padding: 0;
    list-style: none;
}

.point {
    counter-increment: point;
    position: relative;
    padding: 0 0 20px 46px;
    margin-bottom: 20px;
    border-bottom: 1px solid var(--color-border);
}

.point:last-child {
    margin-bottom: 0;
    padding-bottom: 0;
    border-bottom: none;
}

.point::before {
    content: counter(point);
    position: absolute;
    left: 0;
    top: 0;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-accent);
    color: #ffffff;
    font-size: 15px;
    font-weight: 700;
}

.point h3 {
    margin: 3px 0 6px;
    font-size: 19px;
    line-height: 1.25;
}

.point p {
    margin: 0;
    color: var(--color-text-muted);
}

/* ---- The Try it out panel (2026-10-06): the native <dialog> the hero's button
   opens below 820 pixels. White, square, one hairline, like the app's own modals.
   The box fills the dialog so try-panel.js can tell a click outside it from a
   click inside it. ---- */
.try-panel {
    width: min(420px, calc(100vw - 32px));
    max-width: none;
    padding: 0;
    border: 1px solid var(--color-border-strong);
    background: var(--color-surface);
    color: var(--color-text);
}

.try-panel::backdrop {
    background: rgba(19, 20, 23, 0.6);
}

.try-panel-box {
    position: relative;
    padding: 22px 22px 20px;
}

.try-panel h2 {
    margin: 0 36px 8px 0;
    font-size: 20px;
    line-height: 1.25;
}

.try-panel p {
    margin: 0 0 16px;
    color: var(--color-text-muted);
}

/* Ghost, like the app's close buttons: transparent until hovered. */
.try-panel-close {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 32px;
    height: 32px;
    padding: 0;
    background: none;
    border: none;
    color: var(--color-text-muted);
    font-family: inherit;
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
}

.try-panel-close:hover {
    background: var(--color-field);
    color: var(--color-text);
}

/* Full width, stacked: on a phone the two are the whole decision, and a wide target
   is the easiest one to hit. A <button> does not inherit the page's font by itself. */
.try-panel .mk-btn {
    display: block;
    width: 100%;
    text-align: center;
    font-family: inherit;
    cursor: pointer;
}

.try-panel .try-panel-send {
    padding: 13px 18px;
    font-size: 16px;
}

/* What happened after the tap, when the share sheet was not available. Empty until
   then, and taking no space while empty. It loses its margin when empty rather than
   being hidden: a live region that is hidden at the moment its words arrive is not
   read out, so a screen reader would never hear "Link copied". */
.try-panel .try-panel-status {
    margin: 8px 0 0;
    font-size: 13px;
    color: var(--color-text);
    overflow-wrap: anywhere;
}

.try-panel .try-panel-status:empty {
    margin: 0;
}

.try-panel .try-panel-watch {
    margin-top: 12px;
}

.try-panel .try-panel-contact {
    margin: 16px 0 0;
    font-size: 13px;
}

/* The accent, rather than the browser's own link blue, which nothing else on
   these pages wears. */
.try-panel .try-panel-contact a {
    color: var(--color-accent);
}

/* ---- Spreadsheet comparison ---- */
.compare {
    width: 100%;
    max-width: 900px;
    border-collapse: collapse;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
}

.compare th,
.compare td {
    padding: 12px 14px;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--color-border);
    font-size: 14px;
}

.compare tbody tr:last-child th,
.compare tbody tr:last-child td {
    border-bottom: none;
}

.compare thead th {
    font-size: 12px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    border-bottom: 1px solid var(--color-border-strong);
}

.compare tbody th {
    width: 22%;
    font-weight: 700;
    color: var(--color-text);
}

.compare td {
    width: 39%;
    color: var(--color-text-muted);
}

/* Our column carries the accent edge — the eye lands on it without needing
   colour alone to tell the two apart (the row headers already do that). */
.compare .compare-us {
    background: var(--color-surface);
    border-left: 3px solid var(--color-accent);
    color: var(--color-text);
}

.compare thead .compare-us {
    color: var(--color-accent);
    font-weight: 700;
}

/* ============================================================
   Pricing page
   ============================================================ */
/* Side by side, the two cards match height — a short rates card next to a tall
   quote card reads as unfinished. `stretch` is the grid default and needs no
   media query to undo: below the stacking breakpoint each card is its own row,
   so the row sizes to its content and both keep their natural height. Do not
   reinstate `align-items: start`, which was what held them ragged. */
.price-layout {
    display: grid;
    grid-template-columns: 340px 1fr;
    gap: 24px;
    align-items: stretch;
}

.mk-card {
    padding: 20px 22px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
}

.mk-table {
    width: 100%;
    margin: 12px 0;
    border-collapse: collapse;
    font-size: 14px;
}

.mk-table th,
.mk-table td {
    padding: 8px 10px;
    border-bottom: 1px solid var(--color-border);
    text-align: left;
    vertical-align: top;
}

.mk-table th {
    font-size: 12px;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.mk-table .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.mk-table .dim {
    color: var(--color-text-muted);
}

.mk-table .total-row td {
    border-bottom: none;
    border-top: 2px solid var(--color-border-strong);
    font-weight: 700;
    font-size: 15px;
}

.provisional {
    display: block;
    color: var(--color-text-muted);
    font-style: italic;
    font-size: 12px;
}

.calc-label {
    display: block;
    margin: 6px 0 6px;
    font-weight: 600;
}

.calc-input {
    width: 180px;
    padding: 8px 12px;
    background: var(--color-field);
    border: none;
    color: var(--color-text);
    font-family: var(--font-family);
    font-size: 22px;
    font-weight: 600;
}

.calc-totals {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    margin-top: 18px;
}

.calc-total-card {
    padding: 14px 16px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
}

.calc-total-card h3 {
    margin: 0 0 6px;
    font-size: 13px;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.calc-big {
    margin: 0;
    font-size: 26px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.calc-per {
    margin-left: 2px;
    font-size: 14px;
    font-weight: 400;
    color: var(--color-text-muted);
}

.calc-eff {
    margin: 4px 0 0;
    font-size: 13px;
    color: var(--color-text-muted);
}

/* The pre-discount 12-month total under the annual card's headline figure. */
.calc-full {
    margin: 4px 0 0;
    font-size: 13px;
    color: var(--color-text-muted);
}

.calc-saving {
    display: inline-block;
    margin: 6px 0 0;
    padding: 2px 8px;
    background: rgba(62, 124, 77, 0.14);
    color: var(--color-assign-border);
    font-size: 13px;
    font-weight: 600;
}

.calc-annual-note {
    margin: 10px 0 0;
}

.calc-note {
    margin-top: 12px;
    padding: 8px 12px;
    background: rgba(168, 116, 4, 0.12);
    border-left: 3px solid var(--color-warning);
    font-size: 13px;
}

.calc-warning {
    margin-top: 12px;
    padding: 8px 12px;
    background: var(--color-breach);
    color: #ffffff;
    font-weight: 600;
}

.calc-breakdown-title {
    margin: 22px 0 0;
    font-size: 15px;
}

.calc-cta {
    margin-top: 16px;
}

/* ---- "What rostering costs you today": four inputs the visitor owns, then
   the multiplied-out result. Sits between the quote and the small print. ---- */
.spend-card {
    margin-top: 28px;
}

.spend-intro {
    margin: 0 0 16px;
}

.spend-inputs {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px 20px;
    margin-bottom: 20px;
}

.spend-field {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 6px;
    font-size: 14px;
}

.spend-field input {
    width: 120px;
    padding: 6px 10px;
    background: var(--color-field);
    border: none;
    color: var(--color-text);
    font-family: var(--font-family);
    font-size: 17px;
    font-weight: 600;
}

/* Fields carrying a unit: the WELL becomes the field, and the input inside it
   goes transparent, so the % or £ reads as part of the control rather than as
   text sitting next to it. */
.spend-well {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    background: var(--color-field);
}

.spend-well input {
    background: none;
    width: 84px;
}

.spend-unit {
    padding: 6px 10px;
    color: var(--color-text-muted);
    font-size: 17px;
    font-weight: 600;
}

/* The symbol sits against the number, so the digits are aligned towards it:
   right when a suffix follows, left when a prefix leads. Without this the
   number strands itself at the far end of the input and the unit looks detached. */
.spend-unit:first-child { padding-right: 2px; }
.spend-unit:last-child { padding-left: 2px; }
.spend-well input:first-child { padding-right: 4px; text-align: right; }
.spend-well input:last-child { padding-left: 4px; text-align: left; }

/* Focus belongs to the whole well, not the input inside it — an outline drawn
   round the input alone slices through the unit symbol. Visible focus is a house
   rule, so it moves rather than disappears. */
.spend-well:focus-within {
    outline: 2px solid var(--color-accent);
    outline-offset: 1px;
}

.spend-well input:focus-visible {
    outline: none;
}

/* The working, spelled out — the reader should be able to check the arithmetic
   in their head, which is the point of the tool. */
.spend-working {
    margin: 4px 0 10px;
    font-style: italic;
}

/* Tightened on the pre-publication pricing page only (Robert, 2026-07-27): the
   lede and the bullets below it are one thought, so the default 32px + 48px
   between them read as a break that isn't there. Scoped to these two classes so
   /welcome and the full pricing page keep the standard rhythm. */
.pricing-hero { padding-bottom: 20px; }
.pricing-body { padding-top: 20px; }

/* The "email us for the numbers" line on the pre-publication pricing page,
   given a little air so it reads as the ask, not another bullet. */
.pricing-ask {
    max-width: 760px;
    margin: 20px 0 0;
}

.price-notes {
    margin-top: 40px;
}

/* ---- Responsive ---- */

/* ---- Below 820 pixels, the width the live demo needs (DemoSteps.MinimumWidthPx; 1024
   until 2026-10-07, when the demo opened to tablets held upright). The Try it out
   button's name gains " on a laptop or tablet", and try-panel.js turns its tap into
   the panel. When the video is chosen for small screens it takes the pictures' place
   here; otherwise the hero is the carousel or the photograph as at every other width.
   The hero has already stacked at this width (the 900px block). ---- */
@media (max-width: 819px) {
    .mk-btn-try-laptop { display: inline; }

    .mk-hero-video-small .hero-carousel,
    .mk-hero-video-small .hero-photo { display: none; }

    .mk-hero-video-small .hero-video { display: block; padding: 0 24px 28px; }
}

@media (max-width: 900px) {
    .mk-hero h1 { font-size: 28px; }
    .mk-hero-dark h1 { font-size: 30px; }
    .mk-statement p { font-size: 19px; }
    .price-layout { grid-template-columns: 1fr; }

    /* The hero stacks: copy first, then the photo as a full-width band flush
       with the section's bottom edge. Behind-the-text positioning can't
       survive this width. There is no clear side left to read on. */
    .hero-split { grid-template-columns: 1fr; min-height: 0; padding: 40px 24px 32px; }
    .hero-photo { position: static; inset: auto; }
    .hero-photo::after { display: none; }
    .hero-photo img { height: auto; aspect-ratio: 16 / 9; object-position: center; }

    /* The carousel stacks the same way — one column, copy first. The slides need
       nothing else: they are sized by their own images at every width. */
    .mk-hero-dark.mk-hero-carousel { grid-template-columns: 1fr; }
    .hero-carousel { padding: 0 24px 28px; }
    .hero-caption { font-size: 17px; }
}

/* ---- Phones (2026-08-03). Measured on an iPhone 13 before this block existed:
   the first screenshot began 521px down a 664px screen, so a visitor scrolled
   through a full screen of words before seeing the product at all. Everything
   here buys back vertical space above the picture, or gives the picture width.

   Note the ceiling this cannot break: at 390px a 2.9:1 grid screenshot is about
   134px tall, and the grid is not readable at that size whatever we do. The
   picture says "dense colour-coded planner"; the caption carries the meaning.
   Genuine legibility would need a second, zoomed crop per slide. ---- */
@media (max-width: 560px) {
    .calc-totals { grid-template-columns: 1fr; }
    .spend-inputs { grid-template-columns: 1fr; }

    /* One row, not two. Stacking cost about 60px before the page began, and the
       brand plus three links fit at 390px once the padding is trimmed. */
    .mk-header { padding: 10px 16px; }
    .mk-nav { gap: 2px; }
    .mk-nav a { padding: 6px 8px; }

    /* The logo a size down, as the design canvas draws it on a 390px phone. */
    .mk-brand { gap: 9px; }
    .mk-brand .logo-name { font-size: 14px; }

    /* Type a step up on a phone (Robert, 2026-10-08: "The font looks a little too
       small on a mobile"). Until this block every size was the laptop's, carried
       straight to the phone: 15px body copy in the muted ink, 13px small print and
       a 12.5px line inside the Try it out button, where iOS's own reading size is
       17px and the page's width=device-width stops Safari enlarging anything. The
       shell's size is what the numbered points' paragraphs and the pricing page's
       bullets inherit, so one line lifts all of them. Headings are left alone: the
       26px headline, "What it does" at 24px and the 19px point titles read well. */
    .marketing-shell { font-size: 17px; }
    .mk-nav a,
    .mk-footer,
    .mk-small,
    .mk-footnote,
    .hero-video-note { font-size: 14px; }

    .hero-split { padding: 24px 20px 20px; }
    .hero-label { margin-bottom: 10px; font-size: 12.5px; }
    .mk-hero-dark h1 { font-size: 26px; margin-bottom: 12px; }
    .hero-lines { gap: 4px; }
    .hero-line { font-size: 17px; }

    /* On a phone the buttons sit BELOW the carousel or the photograph (Robert,
       2026-10-07: "Put the try now and get in touch button below the carousel on a
       mobile"), so the copy above the pictures is hidden and the one after them is
       shown, with the hero's own side padding. Both buttons show there: Get in touch
       was hidden on a phone from 2026-08-03, because a second button above the
       picture was height a phone could not spare, and below the picture that no
       longer holds. Two classes, to beat .hero-actions' own display rule. */
    .hero-actions.hero-actions-above { display: none; }

    /* Below the pictures the two buttons are one centred column of equal width
       (Robert, 2026-10-07, after seeing them left-aligned under the centred caption
       and arrows, at two different widths: "not visually pleasing"). Full width up
       to 400px, so they line up with each other and sit on the same centre line as
       the carousel's caption and controls; Try it out first and taller, Get in touch
       under it as the quieter outline. The gap above matches the space between the
       caption and the arrows, so the buttons read as part of the same block. */
    .hero-actions.hero-actions-below {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
        width: 100%;
        max-width: 440px;
        margin: 0 auto;
        padding: 6px 20px 28px;
    }

    .hero-actions-below .mk-btn {
        width: 100%;
        justify-content: center;
        text-align: center;
    }

    .hero-actions-below .hero-link { align-self: center; }

    /* The button's name is longer since it says "on a laptop or tablet" (2026-10-07),
       so it may wrap on a narrow phone rather than run past the button's edge. */
    .mk-btn-try-title { white-space: normal; }

    /* The video edge to edge, like the carousel's screenshots, with its note keeping
       the hero's own side padding; 80vh wide keeps the frame inside a short
       window. */
    .mk-hero-video-small .hero-video { padding: 0 0 20px; }
    .hero-video video { width: min(100%, 80vh); }
    .hero-video-note { padding: 0 20px; }

    /* Try it out on a phone (2026-10-06): its second line is about 226px of
       unbreakable text, and with the laptop's 28px sides the button was 283px against
       the 280px a 320px phone leaves (measured), so its sides are 20px here, and the
       second line may wrap on anything narrower still rather than run past the edge. */
    .mk-hero-dark .mk-btn-try {
        max-width: 100%;
        padding-left: 20px;
        padding-right: 20px;
        text-align: center;
    }

    .mk-btn-try-sub { white-space: normal; font-size: 14px; }

    /* Screenshots run edge to edge (Robert, 2026-08-03): every pixel of width is a
       pixel of grid. (The caption kept padding of its own here until it was hidden at
       every width on 2026-10-13; the words are in the picture now.) */
    .hero-carousel { padding: 0 0 20px; }
    .hero-controls { margin-top: 14px; }
}

