/* ==========================================================================
   Notch demo: Vamocles on a 14-inch MacBook Pro in Space Black.
   The screen is built at its real size in points (1512 × 982) and scaled
   once, so 1 du (design unit) = 1 macOS point = 1 CSS px inside .nd__rig.
   Every size, copy line, timer and curve comes from the Mac app (NotchModel,
   NotchView, NotchController, NotchVoiceView, FileScanner).
   Markup: index.html (master), products/index.html, command/index.html.
   Behaviour: js/notch-demo.js, plus js/notch-demo-extras.js on /command/.
   Only transform and opacity animate; the panel's silhouette is twelve
   solid pieces whose transforms are linear in the state numbers, so the
   union stays seamless at every frame and retargets mid-flight.
   ========================================================================== */

@property --k { syntax: "<number>"; inherits: true; initial-value: 0.72; }

/* ---------------------------------------------------- Band, scale, camera */
.nd { margin: 0; }
/* Full bleed without the classic-scrollbar overflow of 100vw: --sbw is the scrollbar width (notch-demo.js) */
.nd__band {
  position: relative;
  width: calc(100vw - var(--sbw, 0px));
  margin-inline: calc(50% - 50vw + var(--sbw, 0px) / 2);
  overflow: clip;
  container: nd-band / inline-size;
  view-timeline: --nd block;
}
/* k reaches 1 (actual size) at 1640px, so the lid always keeps a margin from the window edges */
.nd__stage {
  --band: 640;
  --k: clamp(0.72, tan(atan2(100cqw, 1640px)), 1);
  position: relative;
  height: calc(var(--band) * var(--k) * 1px);
}
@container nd-band (max-width: 639.98px) {
  .nd__stage { --band: 470; --k: min(0.72, tan(atan2(100cqw, 650px))); }
}
/* Where the frame crops the lid (k held at .72), the cut edges dissolve instead of slicing menus and corners */
@container nd-band (min-width: 640px) and (max-width: 1124.98px) {
  .nd:not([data-panned]) .nd__stage {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 min(6vw, 56px), #000 calc(100% - min(6vw, 56px)), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 min(6vw, 56px), #000 calc(100% - min(6vw, 56px)), transparent);
  }
}
.nd__pan, .nd__cam { position: absolute; inset: 0; }
.nd__pan { transform: translateX(calc(var(--pan, 0) * var(--k) * 1px)); transition: transform 400ms var(--ease-in-out); }
.nd__cam { transform-origin: 50% 0; }
.nd__rig {
  position: absolute;
  left: 0;
  top: 0;
  width: 1512px;
  height: 982px;
  transform-origin: 0 0;
  transform: translate(calc(50cqw - 756px * var(--k)), calc(65.5px * var(--k))) scale(var(--k));
}
.nd__fade { position: absolute; inset: auto 0 0; height: 22%; pointer-events: none; background: linear-gradient(rgb(var(--paper-rgb) / 0), var(--paper)); }

/* Establishing shot, pinned. The stage rises into view with the whole laptop (base and shadow included)
   in frame, then holds, centred below the header (scroll-padding-top), for --nd-pin of scroll while one
   slow dolly carries the camera to the close-up; then the page moves on with the move finished. Tied to
   scroll, so it has no duration: 288px of scroll at 1440 × 900, 320px at 1920 × 1080, 230px at 1280 × 720.
   The band carries the timeline; .nd__fade becomes the in-flow spacer the sticky stage travels over, and
   the stage draws the fade itself. The first 10% of the pin rests on the wide shot; the fade is opaque
   before the zoom brings the base to the stage's edge, so the frame never slices the laptop.
   Fill is backwards only: once the range ends the animation has no effect, so the close-up is a plain,
   untransformed layer drawn at full resolution (a held fill keeps it rasterised at an in-between scale).
   Where the scroll comes to rest mid-move, notch-demo.js hands the camera a static copy of its transform
   ([data-hold]) for the same reason, and hands it back on the next scroll. */
@keyframes nd-dolly { from, 10% { transform: scale(0.52); } to { transform: none; } }
@keyframes nd-fadein { from, 8% { opacity: 0; } 32% { opacity: 1; } to { opacity: 1; } }
.nd__band { --nd-pin: clamp(200px, 32vh, 320px); }
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    @container nd-band (min-width: 640px) {
      /* The pin's layout stays when motion is paused page-wide, so the toggle never shifts the page;
         only the camera and the fade stop (the frame then simply holds on the close-up) */
      .nd__stage {
        --nd-h: calc(var(--band) * var(--k) * 1px);
        --nd-top: max(calc(var(--header-h, 72px) + 24px), calc((100vh + var(--header-h, 72px) + 24px - var(--nd-h)) / 2));
        --nd-range: cover calc(100vh - var(--nd-top)) cover calc(100vh - var(--nd-top) + var(--nd-pin));
        position: sticky;
        top: var(--nd-top);
        overflow: clip;
      }
      .nd__fade { position: relative; inset: auto; display: block; height: var(--nd-pin); background: none; }
      .nd__stage::after { content: ""; position: absolute; inset: auto 0 0; height: 22%; pointer-events: none; background: linear-gradient(rgb(var(--paper-rgb) / 0), var(--paper)); }
      html:not([data-motion-paused]) .nd__stage::after { animation: nd-fadein linear backwards; animation-timeline: --nd; animation-range: var(--nd-range); }
      html:not([data-motion-paused]) .nd__cam { animation: nd-dolly cubic-bezier(0.6, 0, 0.6, 1) backwards; animation-timeline: --nd; animation-range: var(--nd-range); }
      html:not([data-motion-paused]) .nd__cam[data-hold] { animation: none; transform: var(--nd-hold); }
    }
  }
}

/* ---------------------------------------------------------- The hardware */
.nd-lid {
  position: absolute;
  left: -25.5px;
  top: -25.5px;
  width: 1563px;
  height: 1080px;   /* chin ≈ 72du below the screen, about 3× the side border */
  border-radius: 36px 36px 10px 10px;
  background: linear-gradient(180deg, #2a2b2e, #1b1c1e);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.07), inset 0 1px 0 rgb(255 255 255 / 0.16);
}
/* Phones crop the lid on both sides, so its top edge would run the full width like a page rule. No rim
   highlight, and the edge dissolves well before the crop (lid centre 781.5px; 50cqw / k is half the
   visible width in du): it reads as the top of a laptop seen close up. Panned to the menu, the lid's
   own corner is in view, so the fade steps aside. */
@container nd-band (max-width: 639.98px) {
  .nd-lid { box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.07); }
  .nd:not([data-panned]) .nd-lid {
    --nd-rim: linear-gradient(90deg, transparent calc(781.5px - 47cqw / var(--k)), #000 calc(781.5px - 14cqw / var(--k)), #000 calc(781.5px + 14cqw / var(--k)), transparent calc(781.5px + 47cqw / var(--k)));
    -webkit-mask-image: var(--nd-rim);
    mask-image: var(--nd-rim);
  }
}
.nd-glass { position: absolute; inset: 6px; border-radius: 30px 30px 6px 6px; background: #000; }
.nd-hinge { position: absolute; left: 14.5px; top: 1054.5px; width: 1483px; height: 10px; background: linear-gradient(#0c0c0d, #1d1e20); }
.nd-base {
  position: absolute;
  left: -53px;
  top: 1064.5px;
  width: 1618px;
  height: 24px;
  border-radius: 2px 2px 40% 40% / 2px 2px 100% 100%;
  background: linear-gradient(#45464a 0 3px, #2c2d30 3px, #17181a);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.14);
}
.nd-base::after { content: ""; position: absolute; left: 42.5%; top: 0; width: 15%; height: 9px; border-radius: 0 0 12px 12px; background: #111; }
.nd-floor { position: absolute; left: -80px; top: 1074.5px; width: 1672px; height: 80px; background: radial-gradient(closest-side, rgb(0 0 0 / 0.55), transparent); }
.nd-sheen { position: absolute; left: -19.5px; top: -19.5px; width: 1551px; height: 1068px; border-radius: 30px 30px 6px 6px; background: linear-gradient(115deg, rgb(255 255 255 / 0.045), transparent 38%); pointer-events: none; z-index: 1; }
/* The camera reads only on close inspection, as in photos of the real notch */
.nd-lens {
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, #151922 0 16%, #07080b 60%, #000);
  box-shadow: 0 0 0 0.5px rgb(255 255 255 / 0.03);
  transition: opacity 200ms var(--ease-soft);
}
.nd-hw .nd-lens { left: 92.5px; top: 13px; }
.nd-lens--bezel { left: 771.5px; top: 5.5px; opacity: 0; }   /* screen (756, −10), in glass space */

/* ------------------------------------------------------------ The screen */
.nd-screen {
  --mbh: 33;
  position: absolute;
  left: 0;
  top: 0;
  width: 1512px;
  height: 982px;
  border-radius: 10px 10px 0 0;
  overflow: clip;
  /* Only black under the screen's anti-aliased top edge, so no grey seam crosses the panel and notch */
  background: linear-gradient(#000 0 2px, #121013 2px);
  color: #fff;
  font: 400 13px/1 var(--font-text);
  letter-spacing: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  cursor: default;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.nd-screen * { cursor: default; }
.nd[data-synth] .nd-screen, .nd[data-synth] .nd-screen * { cursor: none; }   /* one cursor: the drawn one */
.nd-wall, .nd-wall img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.nd-wall { z-index: 0; top: 2px; height: calc(100% - 2px); }

/* Everything in the rig is laid out in points: no fluid media rules */
.nd__rig :is(img, svg, picture) { max-width: none; }
/* glyphs from /assets/img/mac/glyphs.svg; stroke weight follows rendered size */
.nd .g { display: block; flex: none; overflow: visible; stroke-width: var(--gw, 2.2); }

/* Menu bar (Tahoe: transparent, no blur, no scrim) */
.nd-mb {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 2;
  width: 100%;
  height: calc(var(--mbh) * 1px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  text-shadow: 0 0 4px rgb(0 0 0 / 0.35);
}
.nd-mb p { margin: 0; display: flex; align-items: center; }
.nd-mb__menus { gap: 20px; padding-left: 20px; }
.nd-mb__menus b { font-weight: 700; }
.nd-mb__status { padding-right: 12px; }
.nd-mb__item { width: 28px; height: 22px; display: grid; place-items: center; color: #fff; --gw: 2; filter: drop-shadow(0 0 2px rgb(0 0 0 / 0.3)); }
.nd-mb__item--bat { width: 38px; }
.nd-mb__item .g { width: 16px; height: 16px; }
.nd-mb__item--bat .g { width: 25px; height: 12.5px; }
.nd-vhead { display: block; width: 18px; height: 11.5px; background: currentColor; -webkit-mask: url("/assets/img/mac/vamo-menubar@2x.png") center / contain no-repeat; mask: url("/assets/img/mac/vamo-menubar@2x.png") center / contain no-repeat; }
.nd-mb__clock { margin-left: 10px; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Desktop file. Finder hides the extension, which is the lure. */
.nd-file {
  position: absolute;
  left: 934px;
  top: 200px;
  z-index: 1;
  display: block;
  width: 112px;
  height: 108px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: none;
  color: #fff;
  font: 400 12px/15px var(--font-text);
  text-align: center;
  touch-action: none;
  -webkit-touch-callout: none;
}
.nd-file__sel { position: absolute; left: 20px; top: 0; width: 72px; height: 72px; border-radius: 6px; background: rgb(255 255 255 / 0.15); opacity: 0; }
.nd-file__icon, .nd-ghost__icon { position: absolute; left: 24px; top: 4px; width: 64px; height: 64px; }
.nd-file__icon { filter: drop-shadow(0 1px 1.5px rgb(0 0 0 / 0.35)); }
.nd-file__label { position: absolute; left: -6px; top: 76px; width: 124px; }
.nd-file__label span { padding: 0 4px; border-radius: 4px; text-shadow: 0 1px 2px rgb(0 0 0 / 0.6); -webkit-box-decoration-break: clone; box-decoration-break: clone; }
.nd-file.is-selected .nd-file__sel { opacity: 1; }
.is-selected .nd-file__label span, .nd-ghost .nd-file__label span { background: rgb(118 118 128 / 0.92); text-shadow: none; }
.nd-file[aria-disabled="true"] { pointer-events: none; }

/* Pointer and drag image */
.nd-ptr { --ptr-s: max(1, calc(0.706 / var(--k))); position: absolute; left: 0; top: 0; z-index: 6; width: 28px; height: 40px; pointer-events: none; opacity: 0; transition: opacity 120ms var(--ease-soft); }
.nd-ptr.is-on { opacity: 1; transition-duration: 160ms; }
.nd-ptr > svg { position: relative; display: block; filter: drop-shadow(0 1px 1.2px rgb(0 0 0 / 0.35)); transform: scale(var(--ptr-s)); transform-origin: 5px 4px; }
.nd-ghost { position: absolute; left: 0; top: 0; z-index: 5; width: 112px; height: 108px; pointer-events: none; opacity: 0.72; color: #fff; font: 400 12px/15px var(--font-text); text-align: center; transform-origin: 56px 36px; }
.nd-ptr > .nd-ghost { z-index: auto; transform: translate(-39px, -36px); }   /* the arrow paints above the drag image */

/* The hardware notch sits above everything on the screen, as on a Mac. */
.nd-hw { position: absolute; left: 659.5px; top: -2px; z-index: 7; width: 193px; height: 35px; transition: opacity 200ms var(--ease-soft); }
.nd-hw, .nd-hw * { cursor: none; }
.nd-hw svg { display: block; fill: #000; }

/* --------------------------------------------------------- Notch panel */
.np {
  --nw: 185;
  --nh: 32;
  --cx: 756;
  --np-dur: 345ms;
  --np-ease: linear(0, 0.0548, 0.1776, 0.3243, 0.4692, 0.5988, 0.7074, 0.7941, 0.8606, 0.9097, 0.9447, 0.9688, 0.9847, 0.9947, 1);
  --np-delay: 0ms;
  --in-delay: 60ms;
  --r: min(var(--rb), (var(--h) - 10) / 2);
  --ri: calc(10 * (1 - var(--fl)));
  --s6: calc((var(--nh) - 6) * 1px);
  --s4: calc((var(--nh) - 4) * 1px);
  position: absolute;
  left: 0;
  top: 0;
  z-index: 3;
  width: 0;
  height: 0;
  font: 400 12px/15px var(--font-text);
}
@supports not (transition-timing-function: linear(0, 1)) { .np { --np-ease: cubic-bezier(0.2, 0.8, 0.2, 1); } }
.nd[data-display="flat"] .np { --nw: 180; --nh: 24; }
.nd[data-display="flat"] .nd-screen { --mbh: 24; }

/* Poses (unitless du). x0 = left edge, w × h = frame, rb = bottom radius, fl = right edge flush */
.np[data-state="collapsed"] { --x0: calc(var(--cx) - var(--nw) / 2 - 70); --w: calc(54 + var(--nw)); --h: var(--nh); --rb: 12; --fl: 1; }
.np:is([data-state="expanded"], [data-state="voice"]) { --x0: calc(var(--cx) - 300); --w: 600; --h: calc(var(--nh) + 110); --rb: 22; --fl: 0; }
.np:is([data-state="drop"], [data-state="scanning"]) { --x0: calc(var(--cx) - 260); --w: 520; --h: calc(var(--nh) + 72); --rb: 22; --fl: 0; }
.np[data-state="result"] { --x0: calc(var(--cx) - 280); --w: 560; --h: calc(var(--nh) + 102); --rb: 22; --fl: 0; }
.np[data-state="alert"] { --x0: calc(var(--cx) - 250); --w: 500; --h: calc(var(--nh) + 60); --rb: 22; --fl: 0; }
/* Closing: the body contracts at once while the outgoing content fades on the same spring, cut by the
   shrinking clip (SwiftUI's .transition(.opacity) under clipShape), so there is never an empty slab. */
.np[data-dir="shrink"] { --np-delay: 0ms; --in-delay: 60ms; }
.np[data-dir="shrink"] .np-view:not([data-active]) { transition: opacity 260ms var(--np-ease), visibility 0s linear 260ms, transform 0s linear 260ms; }

/* Silhouette: the hairline under-layer (opaque white 9% over the wallpaper top), then the black body.
   Pieces start 2du above the screen edge, so the only top edge is the screen's own (no anti-aliased seam). */
.np-shape { --o: 0; --X: calc(var(--x0) - var(--o)); --W: calc(var(--w) + 2 * var(--o)); --H: calc(var(--h) + var(--o)); --R: calc(var(--r) + var(--o)); --E: calc(var(--X) + var(--W) - var(--ri)); position: absolute; left: 0; top: 0; pointer-events: none; }
.np-shape--ring { --o: 0.5; }
.np-shape > * { position: absolute; left: 0; top: 0; display: block; transform-origin: 0 0; background: #000; fill: #000; transition: transform var(--np-dur) var(--np-ease) var(--np-delay); }
.np-shape--ring > * { background: rgb(55 51 54); fill: rgb(55 51 54); }
.np-shape > [data-p="core"] { width: 100px; height: 100px; transform: translate(calc((var(--X) + 10) * 1px), -2px) scale(calc((var(--W) - 10 - var(--ri)) / 100), calc((var(--H) - var(--R) + 3) / 100)); }
.np-shape > [data-p="band"] { width: 100px; height: 100px; transform: translate(calc((var(--X) + 10 + var(--R) - 0.5) * 1px), calc((var(--H) - var(--R)) * 1px)) scale(calc((var(--E) - var(--X) - 10 - 2 * var(--R) + 1) / 100), calc(var(--R) / 100)); }
.np-shape > [data-p="cl"] { background: none; transform: translate(calc((var(--X) + 10) * 1px), calc((var(--H) - var(--R)) * 1px)) scale(calc(var(--R) / 24)); }
.np-shape > [data-p="cr"] { background: none; transform: translate(calc((var(--E) - var(--R)) * 1px), calc((var(--H) - var(--R)) * 1px)) scale(calc(var(--R) / 24)); }
.np-shape > [data-p="sl"] { background: none; transform: translate(calc(var(--X) * 1px), -2px); }
.np-shape > [data-p="sr"] { background: none; transform: translate(calc((var(--E) - 1) * 1px), -2px); }

/* Content is clipped to the growing body, like SwiftUI's clipShape: two clip boxes
   ride the body's left, right and bottom edges while their children counter-move. */
.np-views, .np-clip, .np-clip__in { position: absolute; left: 0; top: 0; pointer-events: none; }
.np-clip, .np-clip__in { display: block; width: 1512px; height: 982px; transition: transform var(--np-dur) var(--np-ease) var(--np-delay); }
.np-clip { overflow: hidden; }
.np-clip--l { border-bottom-left-radius: 22px; transform: translate(calc((var(--x0) + 10) * 1px), calc((var(--h) - 982) * 1px)); }
.np-clip--l > .np-clip__in { transform: translate(calc((var(--x0) + 10) * -1px), calc((982 - var(--h)) * 1px)); }
.np-clip--r { border-bottom-right-radius: 22px; transform: translate(calc((var(--x0) + var(--w) - var(--ri) - 1512) * 1px), calc((var(--h) - 982) * 1px)); }
.np-clip--r > .np-clip__in { transform: translate(calc((1512 - var(--x0) - var(--w) + var(--ri)) * 1px), calc((982 - var(--h)) * 1px)); }
.np[data-state="collapsed"] .np-clip--l { border-bottom-left-radius: calc(min(12, (var(--nh) - 10) / 2) * 1px); }
.np[data-state="collapsed"] .np-clip--r { border-bottom-right-radius: calc(min(12, (var(--nh) - 10) / 2) * 1px); }

/* Views: each sits at its own final frame and cross-fades */
.np-view {
  position: absolute;
  top: 0;
  left: calc(var(--vx) * 1px);
  width: calc(var(--vw) * 1px);
  height: calc(var(--vh) * 1px);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 100ms var(--ease-soft), visibility 0s linear 100ms, transform 0s linear 100ms;
}
.np-view[data-active] { opacity: 1; visibility: visible; transition: opacity 200ms var(--ease-soft) var(--in-delay), visibility 0s, transform 280ms var(--ease-out) var(--in-delay); }
.np-view :is(button, [data-nd-act]) { pointer-events: auto; }
/* Focus never sits on a view that is still fading in: a quick Tab after Enter shows it at once */
.np-view[data-active]:focus-within { opacity: 1; transform: none; transition: none; }
.np-view[data-view="collapsed"] { --vx: calc(var(--cx) - var(--nw) / 2 - 70); --vw: calc(54 + var(--nw)); --vh: var(--nh); }
.np-view:is([data-view="expanded"], [data-view="voice"]) { --vx: calc(var(--cx) - 300); --vw: 600; --vh: calc(var(--nh) + 110); transform-origin: 50% 0; }
.np-view[data-view="expanded"] { transform: scale(0.98); }
.np-view[data-view="voice"] { transform: scale(0.96); }
.np-view:is([data-view="expanded"], [data-view="voice"])[data-active] { transform: none; }
.np-view:is([data-view="drop"], [data-view="scanning"]) { --vx: calc(var(--cx) - 260); --vw: 520; --vh: calc(var(--nh) + 72); }
.np-view[data-view="result"] { --vx: calc(var(--cx) - 280); --vw: 560; --vh: calc(var(--nh) + 102); }
.np-view[data-view="alert"] { --vx: calc(var(--cx) - 250); --vw: 500; --vh: calc(var(--nh) + 60); }
.np-view p { margin: 0; }

/* Type: the app's SF text styles at macOS sizes */
.np-hl { font-weight: 700; font-size: 13px; line-height: 16px; }
.np-call { font-size: 12px; line-height: 15px; }
.np-cap { font-size: 10px; line-height: 13px; }
.np-c2 { font-size: 10px; line-height: 13px; font-weight: 600; }
.np-dim { color: rgb(255 255 255 / 0.6); }
/* Crimson text in the stage: the light crimson, AA on black (5.84:1) and on the Lock Down tint behind it (4.54:1 at worst) */
.nd { --nd-red: var(--crimson-300); }
.np-red { color: var(--nd-red); }

/* Faces: the Contour head at the app's sizes (box = size × 1.1) */
.np-face { display: block; width: 100%; height: 100%; object-fit: contain; }

/* Lock Down and threat tint, static per view */
.np-tint { position: absolute; left: 10px; right: 10px; top: 0; bottom: 0; border-radius: 0 0 22px 22px; background: linear-gradient(90deg, rgb(200 16 46 / 0.42), rgb(200 16 46 / 0.08) 48%, transparent 96%); opacity: 0; transition: opacity 180ms var(--ease-soft); }
.np-view[data-view="collapsed"] .np-tint { right: 0; border-radius: 0 0 calc(min(12, (var(--nh) - 10) / 2) * 1px) calc(min(12, (var(--nh) - 10) / 2) * 1px); background: linear-gradient(90deg, rgb(200 16 46 / 0.42), rgb(200 16 46 / 0.12) 16%, transparent 24%); }   /* gone before the notch: no tinted block beside it; the halo carries Lock Down */
.nd[data-lock] .np-tint, .np-view:is([data-tone="threat"], [data-tone="lockdown"]) .np-tint { opacity: 1; }

/* collapsed: Vamo on the left wing */
.np-halo { position: absolute; left: 24px; top: calc(var(--nh) * 0.5px - 16px); width: 32px; height: 32px; border-radius: 50%; background: radial-gradient(closest-side, rgb(255 255 255 / 0.26), rgb(255 255 255 / 0)); transition: opacity 180ms var(--ease-soft); }
.np-halo--lock { background: radial-gradient(closest-side, rgb(200 16 46 / 0.55), rgb(200 16 46 / 0)); opacity: 0; }
.nd[data-lock] .np-halo--lock { opacity: 1; }
.nd[data-lock] .np-halo:not(.np-halo--lock) { opacity: 0; }
.np-view[data-view="collapsed"] .np-face { position: absolute; left: 29px; top: calc(var(--nh) * 0.5px - 11px); width: 22px; height: 22px; }

/* expanded: posture, four quick actions, Ask Vamo */
.np-ex__face { position: absolute; left: 13.5px; top: calc(var(--s6) + 5.5px); width: 53px; height: 53px; filter: drop-shadow(0 0 6px rgb(200 16 46 / 0.4)); }
.np-ex__text { position: absolute; left: 78px; top: calc(var(--s6) + 14.5px); display: grid; gap: 6px; }
.np-ex__title { display: flex; align-items: center; gap: 8px; }
.np-status { display: inline-flex; align-items: center; gap: 5px; color: rgb(255 255 255 / 0.75); }
.np-status--lock { display: none; color: var(--nd-red); --gw: 2.6; }
.np-status--lock .g { width: 9px; height: 9px; }
.nd[data-lock] .np-status:not(.np-status--lock) { display: none; }
.nd[data-lock] .np-status--lock { display: inline-flex; }
.np-prot { display: flex; gap: 12px; color: rgb(255 255 255 / 0.85); --gw: 2.6; }
.np-prot span { display: inline-flex; align-items: center; gap: 4px; }
.np-prot .is-off { color: rgb(255 255 255 / 0.38); }
.np-prot .g { width: 9px; height: 9px; }
.np-tiles { position: absolute; right: 16px; top: calc(var(--s6) + 10px); display: flex; gap: 6px; }
.np-tile, .np-btn, .np-ibtn {
  position: relative;
  margin: 0;
  border: 0;
  color: rgb(255 255 255 / 0.85);
  font-family: var(--font-text);
  transition: background-color 180ms var(--ease-soft), color 180ms var(--ease-soft);
}
.np-tile { width: 52px; height: 44px; display: grid; place-content: center; justify-items: center; gap: 4px; padding: 0; border-radius: 10px; background: rgb(255 255 255 / 0.08); font-size: 9px; line-height: 11px; font-weight: 500; --gw: 2.2; }
.np-tile .g { width: 13px; height: 13px; }
.np-tile:is(:hover, :focus-visible, .is-hover) { background: rgb(255 255 255 / 0.16); color: #fff; }
.np-ask { position: absolute; left: 16px; right: 16px; top: calc(var(--s6) + 64px); height: 32px; display: flex; align-items: center; gap: 8px; padding: 0 6px 0 11px; border-radius: 8px; background: rgb(255 255 255 / 0.08); }
.np-ask__q { flex: 1; display: flex; align-items: center; gap: 8px; color: rgb(255 255 255 / 0.35); font-size: 12px; }
.np-ask__q .g { width: 14px; height: 14px; color: rgb(255 255 255 / 0.55); }
.np-ask__btn { width: 20px; height: 20px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 6px; background: rgb(255 255 255 / 0.12); color: rgb(255 255 255 / 0.85); --gw: 2.6; }
.np-ask__btn .g { width: 11px; height: 11px; }
.np-ask__btn--send { background: rgb(255 255 255 / 0.18); color: #fff; }
.np-ask__btn--send .g { width: 10px; height: 10px; }
button.np-ask__btn:is(:hover, :focus-visible) { background: rgb(255 255 255 / 0.2); }

/* drop target */
.np-dash { position: absolute; left: 0; top: var(--s4); overflow: visible; }
.np-dash rect { fill: none; stroke: rgb(255 255 255 / 0.35); stroke-width: 1.5; stroke-dasharray: 6 5; }
.np-drop { position: absolute; left: 16px; top: var(--s4); width: 488px; height: 64px; display: flex; align-items: center; justify-content: center; gap: 12px; --gw: 1.9; }
.np-drop .g { width: 20px; height: 20px; }
.np-drop > span { display: grid; gap: 2px; text-align: left; }

/* scanning */
.np-sc__face { position: absolute; left: 16px; top: calc(var(--s4) + 0.5px); width: 44px; height: 44px; }
.np-sc { position: absolute; left: 72px; right: 18px; top: var(--s4); display: grid; gap: 6px; }
.np-sc__row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.np-sc__pct { font-variant-numeric: tabular-nums; color: rgb(255 255 255 / 0.6); }
.np-bar { position: relative; display: block; height: 4px; border-radius: 2px; overflow: hidden; background: rgb(255 255 255 / 0.14); }
.np-bar i { position: absolute; inset: 0; display: block; border-radius: 2px; background: var(--crimson); transform: translateX(calc((var(--p, 0) - 1) * (100% - 6px))); transition: transform 200ms linear; }
.np-sc__label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* result */
.np-rs__head { position: absolute; left: 18px; right: 18px; top: calc(var(--s4) + 6px); height: 38px; display: flex; align-items: center; gap: 12px; }
.np-rs__face { position: relative; flex: none; width: 38px; height: 38px; }
.np-rs__face .np-face { position: absolute; left: -2px; top: -2px; width: 42px; height: 42px; }
.np-rs__copy { flex: 1; min-width: 0; display: grid; gap: 2px; }
.np-btn { padding: 5px 11px; border-radius: 8px; background: rgb(255 255 255 / 0.1); font-size: 10px; line-height: 13px; font-weight: 600; white-space: nowrap; }
.np-btn:is(:hover, :focus-visible) { background: rgb(255 255 255 / 0.16); }
.np-btn--primary { background: var(--crimson); color: #fff; }
.np-btn--primary:is(:hover, :focus-visible) { background: var(--crimson-600); }
.np-btn.is-pressed { background: rgb(255 255 255 / 0.22); transition-duration: 90ms; }
.np-btn--primary.is-pressed { background: var(--crimson-700); }
.np-rs__find { position: absolute; left: 18px; right: 18px; top: calc(var(--s4) + 50px); height: 22px; display: flex; align-items: center; gap: 8px; }
.np-rs__find .g { width: 13px; height: 13px; margin-inline: 1.5px; color: var(--nd-red); }   /* SF's octagon at 11pt is ~11du across */
.np-rs__title { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: rgb(255 255 255 / 0.9); }

/* Vigilant Eye: life comes from glances and blinks (WAAPI, see notch-demo.js) */
.np-eye { display: block; flex: none; overflow: visible; }

/* Face button: Vamo's spot on the wing, the keyboard and touch way in */
.np-facebtn {
  position: absolute;
  left: calc((var(--cx) - var(--nw) / 2 - 60) * 1px);
  top: 0;
  z-index: 2;
  width: 60px;
  height: calc(var(--nh) * 1px);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0 0 8px 8px;
  background: none;
}
.np-facebtn::before { content: ""; position: absolute; left: 50%; top: 0; width: max(100%, calc(44px / var(--k))); height: max(100%, calc(44px / var(--k))); transform: translateX(-50%); }
.np:not([data-state="collapsed"]) .np-facebtn { pointer-events: none; }
.nd[data-off] .np-facebtn { display: none; }

/* Touch targets: at least 44 CSS px wherever the stage is scaled down */
.np-ask__btn, .nd-mbx { position: relative; }
:is(.np-tile, .np-btn, .np-ibtn, .np-ask__btn, .nd-mbx)::after { content: ""; position: absolute; left: 50%; top: 50%; width: max(100%, calc(44px / var(--k))); height: max(100%, calc(44px / var(--k))); transform: translate(-50%, -50%); }

/* Keyboard focus: instant, sized for the scale, never clipped */
.nd-screen :focus-visible { outline: calc(2px / var(--k)) solid #fff; outline-offset: calc(2px / var(--k)); }
.nd-screen :is(.np-facebtn, .nd-mbx):focus-visible { outline-offset: calc(-2px / var(--k)); }
.nd-screen :focus:not(:focus-visible) { outline: none; }

/* Notch off (command page) and display without a notch */
.np { transition: opacity 200ms var(--ease-soft); }
.nd[data-off] .np { opacity: 0; }
.nd[data-display="flat"] .nd-hw { opacity: 0; pointer-events: none; }
.nd[data-display="flat"] .nd-lens--bezel { opacity: 1; }

/* ---------------------------------------------- Caption plate and controls */
/* The foot spans the page container, so the caption's left edge lines up with the heading and the facts
   below and the controls end on the container's right edge. The caption keeps a readable measure; extra
   controls wrap beneath it rather than squeezing it. Its first line sits on the controls' centre line
   (control height 44px). */
.nd__foot { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 16px 32px; margin: 20px 0 0; }
.nd__caption { flex: 1 1 24rem; max-width: 52rem; display: flex; align-items: flex-start; gap: 10px; min-height: calc(4.5em + 10.75px); min-height: calc(2.5lh + 22px); margin: 0; padding-top: 10.75px; padding-top: calc(22px - 0.5lh); font-size: var(--fs-small); font-weight: 500; line-height: 1.5; color: var(--ink-2); }
.nd__caption > span:first-child { flex: none; display: flex; }
.nd__caption .icon { flex: none; margin-top: 0.15em; color: var(--ink-3); }
.nd__caption .is-threat .icon, .nd__caption b { color: var(--crimson-300); }
.nd__caption b { font-weight: 600; }
.nd__controls { flex: 0 1 auto; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 10px; }
.nd__controls[hidden] { display: none; }
.nd__run { min-width: var(--run-w, 9.5em); justify-content: center; }   /* --run-w: widest label, measured in notch-demo.js */
.nd__controls .btn[aria-pressed="true"] { --btn-bg: rgb(255 255 255 / 0.9); --btn-ink: #0A0A0C; --btn-line: transparent; }
.nd__controls .btn:disabled { opacity: 0.45; cursor: not-allowed; }
.nd__controls .btn[hidden] { display: none; }
.nd-seg { display: inline-flex; gap: 4px; padding: 4px; border-radius: calc(var(--r-xs, 8px) + 4px); background: rgb(255 255 255 / 0.06); border: 1px solid rgb(255 255 255 / 0.1); }
.nd-seg button { min-height: 32px; padding: 0 14px; border: 0; border-radius: var(--r-xs, 8px); background: none; font-size: var(--fs-micro); font-weight: 600; color: var(--ink-3); transition: background-color var(--t-fast, 180ms), color var(--t-fast, 180ms); }
.nd-seg button:hover { color: var(--ink); }
.nd-seg button[aria-checked="true"] { background: rgb(255 255 255 / 0.14); color: var(--ink); }
/* /command/ has five controls: the caption takes its own line (two lines hold every caption at this
   width, so its height never changes), and the controls follow it from the left. */
@media (min-width: 640px) {
  .nd[data-features~="lock"] .nd__caption { flex-basis: 100%; max-width: none; min-height: 3em; min-height: 2lh; padding-top: 0; }
  .nd[data-features~="lock"] .nd__controls { justify-content: flex-start; }
}
@media (max-width: 639.98px) {
  .nd__foot { flex-direction: column; align-items: stretch; }
  .nd__caption { flex: none; min-height: 4.5em; min-height: 3lh; padding-top: 0; }   /* a column: no 24rem basis on the height */
  .nd__controls { justify-content: flex-start; }
  /* /command/: two even columns, the display switch across both */
  .nd[data-features~="lock"] .nd__controls { display: grid; grid-template-columns: 1fr 1fr; }
  .nd[data-features~="lock"] .nd__controls .btn { width: 100%; min-width: 0; justify-content: center; }
  .nd[data-features~="lock"] .nd-seg { grid-column: 1 / -1; }
  .nd[data-features~="lock"] .nd-seg button { flex: 1; }
}
/* The still caption the page ships with runs to four lines up to here. Three were held,
   so the first caption of the run (shorter) pulled the foot and the page below it up a line. */
@media (max-width: 459.98px) { .nd__caption { min-height: 6em; min-height: 4lh; } }

/* Forced colours: controls keep a boundary, and the panel's drawn corners follow its body */
@media (forced-colors: active) {
  :is(.np-tile, .np-btn, .np-ibtn, .np-ask__btn, .nd-mbx, .nd-switch, .nd-menu__cmd) { border: 1px solid ButtonText; }
  .np-shape > svg { fill: Canvas; }
  .np-shape--ring { display: none; }
}

/* QA and init: apply a pose without transitions */
.nd[data-instant] *, .nd[data-instant] *::before, .nd[data-instant] *::after { transition: none !important; }
.nd-timer { position: absolute; width: 0; height: 0; overflow: hidden; }

@media print {
  .nd__band { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
  .np { --x0: calc(var(--cx) - 280) !important; --w: 560 !important; --h: calc(var(--nh) + 102) !important; --rb: 22 !important; --fl: 0 !important; opacity: 1 !important; }
  .np-shape > *, .np-clip, .np-clip__in { transition: none !important; }
  .nd-file__sel { opacity: 1 !important; }
  .nd-file__label span { background: rgb(118 118 128 / 0.92); text-shadow: none; }
  /* Only the still text, whatever the caption holds (child elements, or the markup's own text node) */
  .nd__caption[data-still] { font-size: 0; gap: 0; }
  .nd__caption[data-still] > * { display: none !important; }   /* beats .nd__caption > span:first-child { display: flex } */
  .nd__caption[data-still]::after { content: attr(data-still); font-size: var(--fs-small); }
  .np-view { opacity: 0 !important; visibility: hidden !important; }
  .np-view[data-view="result"] { opacity: 1 !important; visibility: visible !important; transform: none !important; }
  .nd__cam { animation: none !important; transform: none !important; }
  .nd__stage { position: relative !important; top: auto !important; }
  .nd__stage::after { display: none !important; }
  .nd__fade, .nd-ptr, .nd-ghost, .nd__controls, .np-tint, .nd-menu, .np-facebtn { display: none !important; }
}

/* =========================================== /command/: alert, voice, menu */
/* Alert (NotchView.alertView): a plain glyph, never a filled tile */
.np-al { position: absolute; left: 18px; right: 18px; top: var(--s4); height: 34px; display: flex; align-items: center; gap: 12px; }
.np-al__ic { flex: none; width: 34px; height: 34px; display: grid; place-items: center; color: var(--nd-red); --gw: 2; }
.np-al__ic .g { width: 18px; height: 18px; }
.np-view[data-tone="info"] .np-al__ic { color: rgb(255 255 255 / 0.85); }
.np-al__copy { flex: 1; min-width: 0; display: grid; gap: 2px; }
.np-al__copy .np-cap { color: rgb(255 255 255 / 0.65); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.np-btn--view { background: rgb(255 255 255 / 0.14); color: #fff; }

/* Voice (NotchVoiceView): orb with Vamo beside it, caption stream, mute and end */
.np-vo { position: absolute; left: 0; right: 0; top: var(--s6); height: 100px; display: flex; align-items: center; gap: 12px; padding: 0 18px 0 10px; }
.np-vo__stage { position: relative; flex: none; width: 136px; height: 100px; }
.np-orb { position: absolute; left: 30px; top: 12px; width: 76px; height: 76px; border-radius: 50%; overflow: hidden; isolation: isolate; background: radial-gradient(circle at 50% 45%, rgb(61 8 20), rgb(30 3 9)); box-shadow: 0 0 15px rgb(200 16 46 / 0.35), inset 0 0 0 1px rgb(255 255 255 / 0.1); }
.np-orb::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: 50%; background: linear-gradient(rgb(255 255 255 / 0.42), transparent 50%); }
/* VoiceOrb: five blobs at .88, normal blending, diameters .45/.35/.5/.25/.3 of the orb, on their orbits */
.np-orb i { position: absolute; inset: 0; }
.np-orb i::before { content: ""; position: absolute; border-radius: 50%; filter: blur(8px); opacity: 0.88; }
.np-orb i:nth-child(1)::before { left: 42px; top: 21px; width: 34px; height: 34px; background: #DB1233; }
.np-orb i:nth-child(2)::before { left: 24.5px; top: 41.5px; width: 27px; height: 27px; background: #FA597A; }
.np-orb i:nth-child(3)::before { left: -5.5px; top: 19px; width: 38px; height: 38px; background: #9E051F; }
.np-orb i:nth-child(4)::before { left: 28.5px; top: 15px; width: 19px; height: 19px; background: #FFC7D1; }
.np-orb i:nth-child(5)::before { left: 40px; top: 40px; width: 23px; height: 23px; background: #ED338C; }
.np-vo__vamo { position: absolute; left: 73.5px; top: 31.5px; width: 73px; height: 73px; -webkit-mask-image: linear-gradient(#000 62%, transparent 93%); mask-image: linear-gradient(#000 62%, transparent 93%); }
.np-vo__mid { flex: 1; min-width: 0; display: grid; gap: 3px; }
.np-vo__state { color: rgb(255 255 255 / 0.5); }
.np-vo__stream { height: 76px; display: flex; flex-direction: column; justify-content: flex-end; gap: 4px; overflow: hidden; font-size: 10px; line-height: 13px; font-weight: 500; -webkit-mask-image: linear-gradient(transparent, #000 35%); mask-image: linear-gradient(transparent, #000 35%); }
.np-vo__stream p { margin: 0; }
.np-vo__you, .np-vo__live { color: rgb(255 255 255 / 0.6); }
.np-vo__vamo-line { color: rgb(255 255 255 / 0.32); }
.np-vo__vamo-line span { color: rgb(255 255 255 / 0.92); }
.np-vo__btns { flex: none; display: flex; gap: 8px; }
.np-ibtn { width: 30px; height: 30px; display: grid; place-items: center; padding: 0; border-radius: 8px; background: rgb(255 255 255 / 0.12); color: #fff; --gw: 2.6; }
.np-ibtn .g { width: 12px; height: 12px; }
.np-ibtn:is(:hover, :focus-visible) { background: rgb(255 255 255 / 0.2); }
.np-ibtn[aria-pressed="true"] { background: rgb(255 255 255 / 0.24); }

/* Menu bar item and its menu (MenuBarView): graphite highlights, never blue */
.nd-mbx { margin: 0; padding: 0; border: 0; border-radius: 6px; background: none; font: inherit; transition: background-color 180ms var(--ease-soft); }
.nd-mbx:hover, .nd-mbx[aria-expanded="true"] { background: rgb(255 255 255 / 0.2); }
.nd-menu { position: absolute; top: 37px; z-index: 4; display: grid; gap: 12px; width: 300px; padding: 14px; border-radius: 12px; background: rgb(30 30 34 / 0.86); -webkit-backdrop-filter: blur(20px) saturate(150%); backdrop-filter: blur(20px) saturate(150%); box-shadow: inset 0 0 0 0.5px rgb(255 255 255 / 0.12), 0 12px 32px rgb(0 0 0 / 0.45); color: #fff; font-size: 13px; line-height: 16px; text-shadow: none; }
.nd-menu[hidden] { display: none; }
.nd-menu.is-closing { opacity: 0; transition: opacity 150ms var(--ease-soft); }
.nd-menu p { margin: 0; }
.nd-menu__head { display: flex; align-items: center; gap: 12px; }
.nd-menu__face { flex: none; width: 40px; height: 40px; margin: -2px; }
.nd-menu__head p { flex: 1; display: grid; gap: 2px; }
.nd-menu__head b { font-weight: 700; }
.nd-menu__head span { font-size: 11px; line-height: 13px; color: rgb(255 255 255 / 0.55); }
.nd-menu__eye { display: grid; place-items: center; }
.nd-menu__eye .g { display: none; width: 14px; height: 14px; color: var(--nd-red); }
.nd[data-lock] .nd-menu__eye .np-eye { display: none; }
.nd[data-lock] .nd-menu__eye .g { display: block; }
.nd-menu__sep { display: block; height: 1px; background: rgb(255 255 255 / 0.1); }
.nd-menu__row { display: flex; align-items: center; justify-content: space-between; }
.nd-switch { position: relative; flex: none; width: 26px; height: 15px; margin: 0; padding: 0; border: 0; border-radius: 7.5px; background: rgb(255 255 255 / 0.22); transition: background-color 180ms var(--ease-soft); }
.nd-switch i { position: absolute; left: 1.5px; top: 1.5px; width: 12px; height: 12px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgb(0 0 0 / 0.3); transition: transform 280ms var(--ease-out); }
.nd-switch[aria-checked="true"] { background: var(--crimson); }
.nd-switch[aria-checked="true"] i { transform: translateX(11px); }
.nd-switch::after { content: ""; position: absolute; left: 50%; top: 50%; width: max(100%, calc(44px / var(--k))); height: max(100%, calc(44px / var(--k))); transform: translate(-50%, -50%); }
.nd-menu__cmd { display: flex; align-items: center; gap: 8px; width: 100%; height: 16px; margin: 0; padding: 0; border: 0; border-radius: 4px; background: none; color: #fff; font: inherit; text-align: left; }
.nd-menu__cmd .g { width: 14px; height: 14px; color: rgb(255 255 255 / 0.85); --gw: 2.2; }
