/* ============================================================
 * THE SITE V4 CHROME SHEET. The header row, the phone menu, the footer's
 * links and the way a hash is set, on every cut surface.
 * ============================================================
 *
 * WHY A SECOND SHEET, AND WHY NO PAGE LINKS IT ITSELF. Every page links the
 * surface sheet with a hash of its bytes (scripts/sync-asset-versions.ts), so a
 * line added there restamps the head of every page that links it, and one of
 * those heads is being edited by another change. The cut surfaces are also
 * canvas output that the next recut rewrites wholesale. So this sheet is linked
 * at serve time: withChrome (src/lib/site/site-v4-chrome.ts) puts it in the
 * head of every promoted surface as the page is served, and the surface script
 * links it on a page served without that transform, such as a preview.
 *
 * WHAT IT DOES NOT OWN. Colour, type and motion still come from
 * /_shared/site-v4-tokens.css. Nothing here writes a brand value, a duration or
 * an easing: every one redirects through the --v4-* layer.
 *
 * Measured against the live site on 2026-09-29 at 1440 and 390 before any of
 * this existed: the header wrapped onto a second row on four pages, a hero rose
 * into the header on /products/security, a phone reached two of the seven nav
 * destinations, the footer linked no legal page, and a hash broke wherever the
 * line ran out.
 * ============================================================ */

/* ---- ONE ROW OF HEADER. The row needs the width of the mark, the tagline,
     six links and two actions, which is more than the viewport holds between
     the menu's breakpoint and a wide desktop. The tagline is the one cell the
     row can lose without losing a destination, the same trade the phone cut
     already makes below 700, so it steps out until the row fits again. ---- */
@media (min-width: 901px) and (max-width: 1199px) {
  .nav .tagline { display: none; }
}
/* The paper surfaces seat the header inside their masthead and held the
   masthead to the text's measure, 52rem, which is narrower than the row needs:
   at 1440 the row wrapped under the mark and the header ran down onto the
   eyebrow. The measure belongs to the text, which carries its own. */
.site-v4 .masthead { max-width: none; }

/* ---- THE CAMERA'S SHOTS STAND BELOW THE HEADER. A shot is centred in the
     sticky stage, and a shot taller than the room left under the header rose
     into it: on /products/security the eyebrow printed over the wordmark. The
     shot now stands between two clearances the header's height, centred when
     it fits, which leaves every shot that fitted exactly where it was, and
     aligned to the top clearance when it does not, so it can never reach the
     header. The box now spans the stage, so it passes the pointer through and
     only its contents take it, which keeps a hidden shot from covering more of
     the visible one than it did before. Inside the same three gates as the
     camera, so the static composition is untouched. The clearance is the
     header's padding and its tallest control with a little air under them, not
     its whole box: the header's lower padding is empty, and every pixel of it
     given to a tall shot is a pixel less cut off at the foot of the frame. ---- */
.site-v4 { --v4-nav-clear: 5.5rem; }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    @media (min-width: 700px) {
      .orbit .shot {
        top: var(--v4-nav-clear);
        bottom: var(--v4-nav-clear);
        transform: none;
        justify-content: center;
        justify-content: safe center;
        pointer-events: none;
      }
      .orbit .shot > * { pointer-events: auto; }
    }
    /* Without script the header carries its links as a second row below 900,
       so the clearance grows by that row. */
    @media (min-width: 700px) and (max-width: 900px) {
      .orbit .stage:has(> .nav:not([data-v4-menu])) { --v4-nav-clear: 9rem; }
    }
  }
}

/* ---- THE FIRST SHOT FITS ITS FRAME. The camera pins every shot in a frame
     the height of the viewport, and whatever runs past the foot of the frame
     is cut off where no scroll reaches it. A first shot that carries a live
     line is the tallest kind, and on a laptop screen the tallest of those ran
     off the foot: /products/security lost the bottom of its hero at 1366x768
     and 1280x720, and /products/trust and /trust lost theirs at 1280x720. So,
     for that kind of first shot only, which leaves the front door's alone:
     the headline keeps its own measure, 17ch, where the frame's 44rem had
     pushed the longest one onto a fifth line; and on a short screen its size
     answers to the height as well as the width, stepping down from the
     display size only below the height the tallest of these shots needs, and
     only as far as clears the frame with a little air. The rest of the shot
     keeps the frame's measure. Inside the camera's three gates, like the rules
     above. ---- */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    @media (min-width: 700px) {
      .orbit .shot-1:has(> .live-line) { max-width: none; }
      .orbit .shot-1:has(> .live-line) > :not(h1):not(.lede) { max-width: 44rem; }
      .orbit .shot-1:has(> .live-line) > h1 { font-size: min(var(--v4-display-1), max(2.5rem, 25.5vh - 8.3rem)); }
    }
  }
}

/* ---- THE PHONE MENU. Below 900 the list does not fit the row, so the surface
     script adds a button that opens the list as a sheet: the same links as the
     desktop nav, plus Sign in. The sheet IS the site nav, restyled, so it can
     never list a different set of destinations from the one the desktop shows,
     including the Products item promotion adds at serve time. ---- */
.v4-menu-toggle { display: none; }
.nav-links .v4-menu-signin { display: none; }

@media (max-width: 900px) {
  /* WITHOUT SCRIPT the links stay reachable: the button never arrives, so the
     list stands as a second row under the mark and scrolls sideways if it has
     to, each link a full touch target. */
  .nav:not([data-v4-menu]) .nav-links { display: flex; order: 3; flex: 1 0 100%; gap: 0 1.25rem; overflow-x: auto; scrollbar-width: none; }
  .nav:not([data-v4-menu]) .nav-links a { display: inline-flex; align-items: center; min-height: 2.75rem; white-space: nowrap; }

  /* WITH SCRIPT, the button, and Sign in moves into the sheet so the row keeps
     the mark, the one action and the button. */
  .nav[data-v4-menu] .v4-menu-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 2.75rem; min-height: 2.75rem; padding: 0 0.875rem;
    font: inherit; font-size: 0.875rem; font-weight: 600;
    color: var(--v4-ink); background: transparent;
    border: 1px solid var(--v4-rule-strong); border-radius: var(--v4-radius);
    cursor: pointer;
    transition: border-color var(--v4-motion-fast) var(--v4-ease-enter);
  }
  .nav[data-v4-menu] .v4-menu-toggle:hover,
  .nav[data-v4-menu] .v4-menu-toggle[aria-expanded="true"] { border-color: var(--v4-ink); }
  .nav[data-v4-menu] .nav-actions .signin { display: none; }
  .nav[data-v4-menu] .nav-actions .btn { display: inline-flex; align-items: center; min-height: 2.75rem; }

  /* OPEN: the header takes the whole viewport on the page's own ground, the
     row stays where it was, and the list runs down under it. Fixed rather than
     absolute, so a reader who opens it from partway down a camera track still
     sees the whole sheet. */
  .nav[data-v4-menu][data-open] {
    position: fixed; inset: 0; z-index: 20;
    align-content: flex-start; overflow-y: auto; overscroll-behavior: contain;
    background: var(--v4-canvas);
  }
  .nav[data-v4-menu][data-open] .nav-links {
    display: flex; flex-direction: column; order: 3; flex: 1 0 100%;
    gap: 0; margin-top: 0.75rem; border-top: 1px solid var(--v4-rule);
    font-size: 1.125rem;
  }
  .nav[data-v4-menu][data-open] .nav-links a {
    display: flex; align-items: center; min-height: 3rem;
    border-bottom: 1px solid var(--v4-rule); color: var(--v4-ink);
  }
  .nav[data-v4-menu][data-open] .nav-links a[aria-current="page"] { font-weight: 600; }
  .nav[data-v4-menu][data-open] .nav-links .v4-menu-signin { display: flex; color: var(--v4-ink-secondary); }
  /* The camera's sticky stage is its own stacking context, so it rises with
     the open header or the paper sheet would paint over the menu. */
  .stage:has(> .nav[data-open]) { z-index: 20; }
}
/* The sheet arrives with a short drop only for a reader who has not asked for
   less motion. Under reduced motion it simply appears. */
@media (max-width: 900px) and (prefers-reduced-motion: no-preference) {
  .nav[data-v4-menu][data-open] .nav-links { animation: v4-menu-in var(--v4-motion-base) var(--v4-ease-enter) both; }
}
@keyframes v4-menu-in { from { opacity: 0; transform: translateY(-0.5rem); } to { opacity: 1; transform: none; } }

/* ---- THE FOOTER'S LINKS: privacy, terms, the DPA, the security posture,
     contact and status, each a page that answers. A row of its own under the
     ledger row and the imprint, so the ledger row still reads as one line. ---- */
.v4-foot-links { flex: 1 0 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 0 1.25rem; margin: 0; font-size: 0.75rem; }
.v4-foot-links a { color: var(--v4-ink-secondary); text-decoration: none; }
.v4-foot-links a:hover { color: var(--v4-ink); }
@media (max-width: 900px) { .v4-foot-links a { display: inline-flex; align-items: center; min-height: 2.75rem; } }

/* ---- A HASH, SET AS FOUR GROUPS OF SIXTEEN. The surface script writes the 64
     characters as four spans with a break opportunity between them, so a hash
     reads in pieces, wraps between groups whatever break-anywhere rule its
     container carries, and copies back as the 64 characters with no space in
     them: the gap is a margin, never a character. A group breaks inside itself
     only in a box too narrow to hold sixteen characters, where the one
     alternative is a clipped hash. ---- */
.v4-hash > span { word-break: normal; overflow-wrap: break-word; }
.v4-hash > span:not(:last-child) { margin-right: 0.6ch; }
/* The receipt page lists its fields beside their labels, which at a phone's
   width left a value about eleven characters, less than one group. Below 700
   each label stands above its value instead, as the shared panels do. */
@media (max-width: 700px) {
  .site-v4 .fields { grid-template-columns: minmax(0, 1fr); row-gap: 0; }
  .site-v4 .fields dd { margin-bottom: var(--oddly-space-4); }
}

/* ---- A SENTENCE IN A RECEIPT ROW WRAPS AT ITS SPACES. The surface sheet lets
     a receipt row break anywhere, because a row usually holds a hash or a key.
     The price list's rows hold canon's sentences, and at 390 that rule split
     words in half ("Search C / onsole"). A token longer than the row, which only
     a hash or an address can be, still breaks rather than running off it. ---- */
.receipt dd[data-canon] { word-break: normal; overflow-wrap: break-word; }
