/* ==========================================================================
   Tiers.

   The Figma has no mobile frame. This is the proposed behaviour, flagged for
   sign-off in the architecture note: same markup throughout, with drag unbound
   and the windows reflowed into a scrolling stack below 768px.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Narrow desktops — --u already fits both axes, so the composition holds; the
   services rows just need fewer columns to stay readable at that scale.
   -------------------------------------------------------------------------- */

@media (max-width: 1179.98px) and (min-width: 1024px) {
    .hxp-service {
        grid-template-columns: calc(120 * var(--u)) minmax(0, 1fr);
        gap: calc(16 * var(--u)) calc(22 * var(--u));
    }

    .hxp-service__title {
        font-size: calc(30 * var(--u));
    }

    .hxp-service__body,
    .hxp-service__bullets {
        grid-column: 2;
    }
}

/* --------------------------------------------------------------------------
   Mobile — a desktop metaphor stops being useful. The windows become a
   scrolling stack of cards; the taskbar becomes the nav.
   -------------------------------------------------------------------------- */

@media (max-width: 1023.98px) {
    :root {
        --u-base: 1px;   /* the stack is laid out in real pixels, not scaled */
        --u: 1px;
        --taskbar-h: 44px;
        --win-pad: 16;
        --win-bar-h: 44;
        --t-title: 15;
        --t-lead: 15;
        --t-body: 15;
        --t-eyebrow: 11;
        --t-micro: 11;
    }

    body {
        overflow: auto;
        -webkit-text-size-adjust: 100%;
    }

    .hxp-desktop {
        position: relative;
        inset: auto;
        min-height: 100dvh;
        padding-bottom: var(--taskbar-h);
        overflow: visible;
    }

    .hxp-wallpaper {
        position: fixed;
    }

    /* --- header pills stack above the content --- */

    .hxp-logo,
    .hxp-nav {
        position: relative;
        left: auto;
        right: auto;
        top: auto;
        height: auto;
    }

    .hxp-logo {
        margin: 12px 12px 0;
        width: max-content;
        padding: 9px 14px;
        gap: 12px;
    }

    .hxp-logo__mark { width: 30px; height: 30px; }
    .hxp-logo__mark img { width: 17px; }
    .hxp-logo__rule { height: 25px; }
    .hxp-logo__word img { width: 63px; }

    /* The nav is the index on a phone, so it comes with you, and all four
       items stay on one line at every width - scaled to fit rather than
       wrapped, cropped or pushed off the side. stack.js still measures the
       height into --nav-h, because one line at 320px is not the same height as
       one line at 768. */
    .hxp-nav {
        position: sticky;
        top: 10px;
        z-index: 120;
        margin: 10px 12px 0;
        padding: 4px 6px;
    }

    /* Centred, with one even gap between items. space-between spread them to
       the pill's edges, which puts a different amount of air outside the first
       and last than between any two of them - even by the letter, uneven to
       look at. */
    .hxp-nav__list {
        /* The nav is itself a flex row, so the list is a flex item and sizes to
           its content - centring inside a box that is only as wide as what it
           holds does nothing. It has to span the pill before it can centre in
           it. */
        flex: 1;
        flex-wrap: nowrap;
        justify-content: center;
        gap: clamp(2px, 1.4vw, 12px);
    }

    .hxp-nav__list li + li { border-left: 0; }

    /* Fluid, so the row fits itself to the screen instead of the screen having
       to be wide enough for the row. The floors are what "Track Record" needs
       to stay on one line and uncropped at 320px; the ceilings stop it growing
       past the size it had before on a tablet. */
    .hxp-nav__list a {
        /* The horizontal spacing is the list's gap now, so the padding here is
           only what keeps the tap target tall and the label off its own edge. */
        padding: 10px clamp(3px, 1.1vw, 10px);
        font-size: clamp(11.5px, 3.3vw, 15px);
        white-space: nowrap;
    }

    /* The Galaxy Fold's cover screen is 280px. Bold, the row at the 11.5px floor
       came out a pixel wider than the pill there. A step down for that width
       alone, rather than a lower floor everywhere, so a 320px phone keeps the
       size it has. */
    @media (max-width: 300px) {
        .hxp-nav__list {
            gap: 2px;
        }

        .hxp-nav__list a {
            font-size: 11px;
        }
    }

    /* --- windows become a stack ------------------------------------- */

    .hxp-windows {
        position: relative;
        inset: auto;
        display: flex;
        flex-direction: column;
        gap: 14px;
        padding: 14px 12px 20px;
    }

    .hxp-win,
    .hxp-win[data-state="max"] {
        position: relative;
        left: auto;
        top: auto;
        width: 100%;
        height: auto;
        z-index: auto;
        translate: none;
        /* Kept clear of the sticky nav. The browser does the scrolling; this is
           the only place that has to know the nav is there. */
        /* The nav sticks 10px down and is --nav-h tall, so clearing it alone
           leaves the widget touching its underside. The extra is the same
           breathing room the widgets keep from each other. */
        scroll-margin-top: calc(var(--nav-h, 94px) + 24px);
    }

    /* Minimised means nothing without a desktop - show everything. */
    .hxp-win[data-state="min"],
    .hxp-win[data-state="closed"] {
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
    }

    .hxp-win__bar {
        cursor: default;
    }

    /* --- the stack is an accordion ----------------------------------- */

    /* Collapsed, a widget is its title bar and nothing else - so every one of
       them is the same height, whatever it holds. The narrow frames set their
       own auto-height bar for the desktop's 117-unit widgets; here they are all
       the full width of the phone and share one. */
    .hxp-win[data-stack] .hxp-win__bar {
        height: 52px;
        min-height: 0;
        align-items: center;
        padding-block: 0;
        cursor: pointer;
    }

    .hxp-win[data-stack="shut"] .hxp-win__body,
    .hxp-win[data-stack="shut"] .hxp-win__segments {
        display: none;
    }

    /* Only the open widget opens a band above itself for the sticky nav to sit
       in. Carrying that space in every gap meant the stack was mostly wallpaper
       between eight collapsed bars, to hold a bar that is only ever over one of
       them. The first widget is exempt: the nav is already above it in flow.

       No transition on this. The margin has to be at its final value before
       scrollIntoView measures, or the scroll lands where the widget used to be
       - so it is applied whole and the smooth scroll covers it. Collapsing
       compensates in stack.js instead. */
    .hxp-windows > .hxp-win[data-stack="open"] {
        margin-top: calc(var(--nav-h, 94px) + 10px);
    }

    .hxp-windows > .hxp-win[data-stack="open"]:first-child {
        margin-top: 0;
    }

    /* Something has to say it can be opened. A chevron that turns is the
       cheapest honest signal, and it is the only thing added to the bar. */
    .hxp-win[data-stack] .hxp-win__bar::before {
        content: "";
        order: 99;
        flex: 0 0 auto;
        margin-left: auto;
        width: 9px;
        height: 9px;
        border-right: 2px solid var(--ink-muted);
        border-bottom: 2px solid var(--ink-muted);
        rotate: 45deg;
        translate: 0 -2px;
        transition: rotate 0.2s var(--ease), border-color 0.2s var(--ease);
    }

    .hxp-win[data-stack="open"] .hxp-win__bar::before {
        rotate: -135deg;
        translate: 0 2px;
        border-color: var(--harry-yellow);
    }

    /* The player's controls wait until there is a player to control. */
    .hxp-win[data-stack="shut"] .hxp-player__transport {
        display: none;
    }

    /* Open, the controls and the chevron would both push right with an auto
       margin and split the free space between them, parking the controls in
       the middle of the bar. The controls take the push; the chevron follows. */
    .hxp-win[data-stack="open"] .hxp-win__bar:has(.hxp-player__transport)::before {
        margin-left: 12px;
    }

    /* The pill counts how far you have scrolled through the cards. Collapsed,
       there is nothing to scroll and every one of them reads 100%, which is
       both wrong and the loudest thing on the row. */
    .hxp-win[data-stack="shut"] .hxp-win__progress {
        display: none;
    }

    /* The bar is the control now, so the things inside it that used to be one
       stand down: the title link only points at a route that expands this same
       widget, the lights do nothing on a stack where a minimised window is
       shown anyway, and a "See more" pill inside a header that is itself a
       button is two controls in one target. */
    .hxp-win[data-stack] .hxp-win__title-link {
        pointer-events: none;
    }

    .hxp-lights,
    .hxp-win[data-stack] .hxp-win__bar .hxp-btn {
        display: none;
    }

    /* Every headline reads down one left edge. Two things were stopping that:
       Clippy and the big button centre their titles on the desktop, where they
       are narrow widgets whose name labels the thing underneath; and --win-pad
       is tuned per window - 16 here, 13 on the narrow frames, 9 on the gimmick
       - which is what a 117-unit widget needs and has no meaning once every
       window is the full width of the phone. One padding, one edge. */
    .hxp-win {
        --win-pad: 16;
    }

    .hxp-win[data-stack] .hxp-win__title {
        flex: 0 1 auto;
        text-align: left;
    }

    /* Nothing is dragged or resized on the stack - bindDrag bails out on the
       stacked tier - so `touch-action: none`, which keeps a pointer drag exact
       on the desktop, has nothing to keep exact here. All it does is tell the
       browser not to scroll from these elements: down a column of nine windows
       the title bars are most of what a thumb lands on, so the page simply
       refused to move for a lot of the swipes anyone would actually make. */
    .hxp-win__bar {
        touch-action: auto;
    }

    /* And the grip goes entirely. Resize is unbound here, so it was an 18px
       control that did nothing - announced to a screen reader as "Resize
       Services", and sitting in the corner of every window inviting a drag
       that could never happen. */
    .hxp-win__resize {
        display: none;
    }

    /* --- targets a thumb can actually hit ---------------------------- */

    /* Both of these are real navigation - the pill goes to a section, the
       title goes to the window's own route - and both were under 20px tall,
       which is a coin-flip on a phone. The pill grows; the title keeps its
       type size and stretches its box to the full height of the bar it sits
       in, so the whole row becomes the target rather than the words. */
    .hxp-btn {
        min-height: 44px;
        padding-inline: 18px;
    }

    /* The title link is no longer a tap target of its own - the whole 52px bar
       is - so it needs no height of its own either. */

    .hxp-win__body,
    .hxp-win__body--scroll {
        overflow: visible;
        max-height: none;
    }

    /* The inner scroller is switched off with it, and this is the one that
       actually stopped the page moving.

       `overflow-y: auto` makes an element a scroll container whether or not it
       has anything to scroll, and `overscroll-behavior: contain` then refuses
       to pass the gesture up to the page. On the stack these boxes have nothing
       to scroll - the body above is already `visible` and the windows size to
       their content - so every swipe landing on a window's content, which is
       most of the page, was handed to a container that would neither move
       itself nor let anything else move. */
    .hxp-win__scroll {
        overflow: visible;
        overscroll-behavior: auto;
    }

    /* Fixed-height media needs an aspect ratio once the frame is fluid. */
    .hxp-figure,
    .hxp-player__stage {
        aspect-ratio: 4 / 5;
        height: auto;
    }

    .hxp-player__stage {
        aspect-ratio: 16 / 10;
    }

    .hxp-gimmick,
    .hxp-clippy {
        height: auto;
        padding-block: 8px;
    }

    /* The contact panel is not a widget of its own on the stack: it was a
       second "get in touch" in a list that already has one. Its details show
       under Clippy instead, in place of the button that opens the panel on
       the desktop. stack.js leaves it out of the accordion to match. */
    .hxp-windows > .hxp-win[data-route-mode="open"] {
        display: none;
    }

    .hxp-clippy__cta {
        display: none;
    }

    .hxp-clippy__connect {
        display: block;
        margin-top: 4px;
        text-align: left;
    }

    /* Nothing overlaps on the stack, so there is no widget to pick out of a
       pile - every window is already in plain sight, in order. */
    .hxp-win.is-active {
        border-color: var(--glass-edge);
        --glow: 0 0 0 0 rgba(0, 0, 0, 0);
    }

    /* --- body types collapse to one column --------------------------- */

    .hxp-project,
    .hxp-win[data-state="max"] .hxp-projects,
    .hxp-win[data-state="max"] .hxp-project,
    .hxp-grid,
    .hxp-win[data-state="open"] .hxp-grid {
        grid-template-columns: 1fr;
    }

    .hxp-project {
        gap: 12px;
    }

    /* On the stack every card should show, maximised or not. */
    .hxp-win[data-state="open"] .hxp-card:nth-child(n + 2) {
        display: flex;
    }

    .hxp-win[data-state="open"] .hxp-card .hxp-eyebrow,
    .hxp-win[data-state="open"] .hxp-card .hxp-card__title,
    .hxp-win[data-state="open"] .hxp-card .hxp-card__description,
    .hxp-win[data-state="open"] .hxp-card .hxp-bar {
        display: block;
    }

    .hxp-win[data-state="open"] .hxp-card {
        border-top: 1px solid var(--glass-rule);
        padding-top: 14px;
    }

    .hxp-win[data-state="open"] .hxp-services {
        display: block;
    }

    .hxp-services__intro {
        max-width: none;
    }

    .hxp-service {
        grid-template-columns: 1fr;
        gap: 10px;
        padding: 18px 0;
    }

    .hxp-service__mark {
        flex-direction: row;
        align-items: center;
        gap: 12px;
    }

    .hxp-service__num { font-size: 26px; }
    .hxp-service__title { font-size: 27px; }

    /* --- desktop icons ----------------------------------------------- */

    /* In the flow, after the widgets, over on the right. Not fixed: it is a
       shortcut sitting on the desktop, not a piece of chrome, and pinning it to
       the corner left it hovering over whatever you were reading. */
    .hxp-icons {
        position: relative;
        left: auto;
        right: auto;
        top: auto;
        bottom: auto;
        z-index: auto;
        flex-direction: row;
        justify-content: flex-end;
        padding: 0 12px 20px;
    }

    /* --- taskbar becomes the window switcher ------------------------- */

    .hxp-taskbar {
        position: fixed;
    }

    .hxp-start {
        padding-right: 14px;
    }

    /* The taskbar is fixed here, so the menu that sits on it has to be too -
       absolute would pin it to the bottom of the document instead of the
       bottom of the screen. */
    .hxp-start-menu {
        position: fixed;
        left: 6px;
        right: 6px;
        width: auto;
        max-width: none;
    }

    .hxp-start__label { font-size: 15px; }

    .hxp-tasklist {
        overflow-x: auto;
        scrollbar-width: none;
    }
    .hxp-tasklist::-webkit-scrollbar { display: none; }

    .hxp-tab {
        flex: 0 0 auto;
        min-width: 0;
        height: 24px;
    }

    /* The tray is decoration; the clock earns its place, the icons do not. */
    .hxp-tray__overflow,
    .hxp-tray__icons img {
        display: none;
    }
}

/* --------------------------------------------------------------------------
   Short viewports — a 970-tall composition on a 700-tall laptop needs the
   maximised windows to keep their padding rather than their proportions.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Coarse pointers get bigger hit targets on the window controls.
   -------------------------------------------------------------------------- */

@media (pointer: coarse) {
    .hxp-light {
        width: calc(16 * var(--u));
        height: calc(16 * var(--u));
    }
}

/* --------------------------------------------------------------------------
   Print — flatten to a document.
   -------------------------------------------------------------------------- */

@media print {
    .hxp-taskbar,
    .hxp-icons,
    .hxp-wallpaper,
    .hxp-win__tools {
        display: none !important;
    }

    body { overflow: visible; background: #fff; color: #000; }

    .hxp-desktop { position: static; }

    .hxp-windows {
        position: static;
        display: block;
    }

    .hxp-win {
        position: static;
        display: block;
        width: auto;
        height: auto;
        background: none;
        border: 0;
        border-top: 1pt solid #999;
        border-radius: 0;
        box-shadow: none;
        backdrop-filter: none;
        page-break-inside: avoid;
    }
}
