/* Dela Gothic One (headings) + Space Mono (normal text); latin+vietnamese woff2 subsets. */
@font-face{font-family:'Dela Gothic One';src:url('assets/dela-gothic-one.woff2') format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Space Mono';src:url('assets/space-mono-regular.woff2') format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Space Mono';src:url('assets/space-mono-bold.woff2') format('woff2');font-weight:700;font-display:swap}
/* Google Sans (contact buttons); variable wght 400-700, latin+vietnamese subsets. */
@font-face{font-family:'Google Sans';src:url('assets/google-sans-vietnamese.woff2') format('woff2');font-weight:400 700;font-display:swap;unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'Google Sans';src:url('assets/google-sans-latin.woff2') format('woff2');font-weight:400 700;font-display:swap}
*{box-sizing:border-box}
body{margin:0;padding:0;background:var(--paper);color:var(--ink);font-family:var(--font-body);font-weight:var(--weight-regular);-webkit-font-smoothing:antialiased}
/* One fixed grain film above every surface, incl. fixed chrome; dialogs stay clean. */
body::after{content:'';position:fixed;inset:0;z-index:var(--layer-grain);pointer-events:none;background:url('assets/film-grain.png');background-size:125px;image-rendering:pixelated;opacity:var(--grain-opacity);mix-blend-mode:overlay}
button,a{-webkit-tap-highlight-color:transparent;touch-action:manipulation}
button{font:inherit;color:inherit;cursor:pointer}
button:focus-visible,a:focus-visible{outline:3px solid var(--sun);outline-offset:5px}
.place-note button:focus-visible,.place-note a:focus-visible{outline-color:var(--ink)}
button:active{filter:brightness(.92)}
button:disabled{opacity:.5;cursor:default}
[hidden]{display:none!important}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.skip{position:fixed;z-index:var(--layer-skip);left:20px;top:-80px;background:var(--paper);padding:15px;color:var(--ink)}
.skip:focus{top:20px}
.experience{position:relative;height:100svh;min-height:540px;isolation:isolate;overflow:hidden;background:var(--sea)}
.map-viewport{position:absolute;inset:0;overflow:hidden;container-type:size;touch-action:pan-y pinch-zoom;cursor:grab;background:radial-gradient(ellipse at 62% 50%,#104e5a,var(--sea) 77%)}
.map-viewport[data-dragging]{cursor:grabbing}
/* Keep the complete map at the view's height; only open ocean fills the sides. */
.world{position:absolute;width:150cqh;aspect-ratio:3/2;left:50%;top:50%;transform:translate(-50%,-50%) translateX(var(--pan-x,0px));user-select:none;isolation:isolate}
/* One continuous outpaint under the unchanged map replaces reflected strips.
   Both layers share their height and center; only their ocean margins blend. */
.world::before{content:'';position:absolute;top:0;bottom:0;left:50%;width:max(118.455544%,100cqw);transform:translateX(-50%);z-index:-1;pointer-events:none;background-image:linear-gradient(to bottom,var(--sea),transparent 7%,transparent 90%,var(--sea)),linear-gradient(to right,#ffe8d8 15%,#fff6e8 85%),url('assets/fast/ocean-wide.webp');background-position:center;background-size:100% 100%,100% 100%,cover;background-repeat:no-repeat;background-blend-mode:normal,multiply,normal}
.terrain-art{position:absolute;inset:0;mask-image:linear-gradient(to right,transparent,#000 9%,#000 94%,transparent);-webkit-mask-image:linear-gradient(to right,transparent,#000 9%,#000 94%,transparent)}
.terrain-art::after{content:'';position:absolute;inset:0;pointer-events:none;background:linear-gradient(to bottom,var(--sea),transparent 7%,transparent 90%,var(--sea))}
.terrain-art img{display:block;width:100%;height:100%;object-fit:cover;transition:filter .25s ease-out}
#water{position:absolute;top:0;left:min(0px,calc((100% - 100cqw)/2));width:max(100%,100cqw);height:100%;pointer-events:none}
.spot-layer{position:absolute;inset:0;pointer-events:none}
.spot-layer button{pointer-events:auto}
.edge-wash{position:absolute;inset:0;z-index:var(--layer-wash);pointer-events:none;background:linear-gradient(0deg,#052d3f88,transparent 18%,transparent 88%,#052d3f33)}
.header{position:absolute;left:40px;right:36px;top:36px;z-index:var(--layer-chrome);display:flex;align-items:flex-start;justify-content:space-between;pointer-events:none;--header-r:36px}
.header button{pointer-events:auto}
.brand{position:relative;width:205px;padding:0;border:0;background:none;transform:rotate(-7deg);line-height:0}
.brand-art{display:block;width:100%;height:auto;filter:drop-shadow(0 3px 2px #001c2d22)}
/* Scale stickers with map geometry, capped at their readable desktop size.
   This preserves geographic gaps on short screens and across mobile breakpoints. */
.map-sticker{position:absolute;left:var(--x);top:var(--y);z-index:var(--layer-marker);width:min(var(--sticker-width),var(--sticker-map-width));padding:0;border:0;background:none;transform:translate(-50%,-50%);isolation:isolate}
.sticker-paper{position:relative;display:block;transform:rotate(var(--turn));filter:drop-shadow(1px 2px 1px #001f2c30)}
.landmark-art,.sticker-tape{position:relative;display:block;overflow:hidden}
.landmark-art img,.sticker-tape img{position:absolute;max-width:none;height:auto;pointer-events:none}
.sticker-tape{position:absolute;z-index:1;left:28%;top:-6%;width:48%;transform:rotate(-12deg);pointer-events:none}
.sticker-bachdinh .sticker-tape{left:57%;top:-5%;width:41%;transform:rotate(18deg)}
.sticker-statue .sticker-tape{left:7%;top:-4%;width:48%;transform:rotate(-16deg)}
.sticker-honba .sticker-tape{left:30%;top:-5%;width:43%;transform:rotate(7deg)}
.map-sticker:hover,.map-sticker:focus-visible,.map-sticker[aria-pressed="true"]{z-index:3}
.map-sticker:focus-visible{outline:3px dashed var(--paper);outline-offset:5px}
.map-sticker[aria-pressed="true"] .sticker-paper{filter:drop-shadow(0 0 2px var(--sun)) drop-shadow(1px 2px 1px #001f2c44)}
/* Flat cartographic city name; stays under the sticker pins. */
.map-city{position:absolute;left:var(--x);top:var(--y);transform:translate(-50%,-50%);color:var(--ink);font-family:var(--font-display);font-weight:400;font-size:var(--text-title);line-height:1;letter-spacing:.14em;text-transform:uppercase;white-space:nowrap;pointer-events:none;text-shadow:0 0 3px var(--paper),0 0 7px #f3eddab3,0 0 14px #f3edda80}
.footer{position:absolute;bottom:28px;left:36px;right:36px;z-index:var(--layer-chrome);display:flex;align-items:flex-end;justify-content:space-between;pointer-events:none}
.footer>*{pointer-events:auto}
.location{position:relative;isolation:isolate;width:min(300px,100%);padding:14px 18px 15px;color:#203e4b;font-family:var(--font-body);transform:rotate(-.7deg)}
.location::before{content:'';position:absolute;inset:0 -5px;z-index:-1;background:url('assets/runtime/sailor-location-tape-blank.webp') center/100% 220% no-repeat;filter:drop-shadow(0 2px 1px #152f3526);pointer-events:none}
.wx-head{display:flex;align-items:baseline;justify-content:space-between;flex-wrap:wrap;gap:var(--space-1) 12px}
.wx-place{font-weight:var(--weight-regular);font-size:var(--text-place);line-height:1.4;letter-spacing:.06em;text-transform:uppercase}
.wx-coord,.wx{font-variant-numeric:tabular-nums}
.wx-coord{color:inherit;font:400 .625rem/1.4 var(--font-body);letter-spacing:0;white-space:nowrap}
.wx{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin:7px 0 0}
.wx-metric{min-width:0}
.wx dd{display:flex;align-items:baseline;gap:3px;margin:0;font:1rem/1.3 var(--font-body);letter-spacing:-.5px;white-space:nowrap}
.wx-unit{font:.625rem/1.3 var(--font-body);letter-spacing:0}
.location[data-weather-error] #wx-condition{position:static;display:block;width:auto;height:auto;margin:12px 0 0;padding:0;overflow:visible;clip:auto;white-space:normal;font-size:var(--text-small)}
@media(min-width:761px){
 .footer{left:48px;right:48px;bottom:40px}
}
.place-note{position:absolute;z-index:var(--layer-note);left:5%;top:39%;width:260px;max-height:calc(100% - 180px);overflow:auto;padding:23px 25px 22px;background:var(--paper);box-shadow:var(--shadow-paper);border-radius:var(--radius-sticker);text-align:center;transform:rotate(-2deg)}
.place-note::before{content:'';position:absolute;top:0;left:calc(50% - 30px);width:60px;height:9px;background:#dfbd5888;transform:rotate(3deg)}
.note-art{width:88px;margin:0 auto}.note-art .landmark-art{width:100%}
.note-close{position:absolute;right:2px;top:3px;display:flex;align-items:center;justify-content:center;width:var(--control-size);height:var(--control-size);padding:0;border:0;background:none}
.place-note h2{font-family:var(--font-display);font-size:var(--text-title);font-weight:400;line-height:1.4;margin:var(--space-1) 0 10px}
.place-note p{margin:0 0 10px;font-size:var(--text-body);line-height:1.7}
.place-note a{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:var(--control-size);font-size:var(--text-label);color:var(--ink);text-decoration:underline;text-underline-offset:5px}
.map-error{position:absolute;top:40%;left:25%;right:25%;z-index:var(--layer-status);padding:20px;background:var(--paper);text-align:center}
.map-error button{min-height:var(--control-size);background:var(--sun);border:0;padding:10px;margin:10px}
.ui-icon{display:inline-block;flex-shrink:0;width:22px;height:22px;vertical-align:middle;background-image:url('assets/control-icons.webp');background-repeat:no-repeat;background-size:480% 480%}
.icon-close{background-position:88% 49%}.icon-arrow{background-position:10% 87%}
@media(max-width:1100px) and (min-width:761px){.place-note{left:3%;width:230px}}
@media(max-width:760px){
 .experience{height:100svh;min-height:0}
 .world{width:150cqh;left:50%;top:50%}
 .header{left:19px;right:16px;top:24px;--header-r:16px}
 .brand{width:150px}
 .map-city{font-size:var(--text-reading)}
 .footer{left:16px;right:16px;bottom:18px;align-items:center}
 .place-note{left:50%;top:115px;width:min(285px,calc(100% - 34px));max-height:calc(100% - 215px);padding:18px 24px;transform:translateX(-50%) rotate(-2deg)}
 .note-art{width:66px}
 .place-note h2{font-size:21px}
 .map-error{left:20px;right:20px}
}
@media(max-width:360px){.header{left:15px;right:12px;--header-r:12px}.brand{width:128px}}
@media(max-height:600px) and (min-width:761px){.header{top:20px;left:26px;right:26px;--header-r:26px}.brand{width:150px}.place-note{top:23%;left:4%}.footer{bottom:20px}}
@media(max-height:600px) and (min-aspect-ratio:4/3){.experience{min-height:0}.location{width:220px;padding:10px 12px}.wx-place{font-size:.875rem}.wx-coord{font-size:.5rem}.wx dd{font-size:.875rem}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;transition:none!important;animation:none!important}}

/* Compact chart rose: fine inner graduations, eight points, fixed bearings. */
.compass{width:112px;aspect-ratio:1;padding:0;border:0;background:none;color:#e8d7ac;cursor:grab;touch-action:none;user-select:none;filter:drop-shadow(0 2px 1px #001e2c55)}
.compass svg{display:block;width:100%;height:100%;overflow:visible;pointer-events:none}
.compass-letters{font:400 17px var(--font-body)}
.compass-north{fill:var(--sun);font-weight:var(--weight-semibold)}
.compass-rotor,.compass-needle{transform-origin:100px 100px}
.compass-needle{animation:compass-breeze 7s ease-in-out infinite}
.compass[data-held]{cursor:grabbing}
.compass[data-held] .compass-needle{animation-play-state:paused}
.compass[data-still] .compass-needle{animation:none}
.compass:focus-visible{outline:2px dashed var(--sun);outline-offset:7px;border-radius:50%}
@keyframes compass-breeze{0%,100%{transform:rotate(-1.2deg)}45%{transform:rotate(1.4deg)}75%{transform:rotate(-.4deg)}}
@media(max-width:760px){.compass{width:86px}}
@media(max-width:360px){.compass{width:80px}}
@media(max-height:600px) and (min-width:761px){.compass{width:94px}}

/* One initial sound choice on approved physical paper. */
.sound-welcome{padding:0;border:0;background:none;color:var(--ink);width:min(440px,calc(100vw - 32px));max-width:none;max-height:calc(100svh - 32px);overflow:visible}
.sound-welcome[open]{animation:sound-welcome-arrive .72s cubic-bezier(.22,.61,.36,1) both}
.sound-welcome[open]::backdrop{animation:sound-welcome-veil .72s ease both}
@keyframes sound-welcome-arrive{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes sound-welcome-veil{from{background-color:#062f3a00}to{background-color:#062f3a66}}
.sound-welcome::backdrop{background:#062f3a66}
.sound-welcome-paper{position:relative;isolation:isolate;padding:32px}
.sound-welcome-paper::before{content:'';position:absolute;inset:0;z-index:-1;background:url('assets/instructors/ivory-sheet.webp') center/100% 100% no-repeat;filter:drop-shadow(0 3px 4px #001b2b33)}
.sound-welcome h2{margin:0 0 12px;font:400 clamp(1rem,5vw,1.5rem)/1.4 var(--font-display)}
.sound-welcome p{margin:0 0 22px;font:400 .75rem/1.8 var(--font-body)}

.sound-welcome-actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.sound-welcome button{display:flex;min-width:0;width:100%;align-items:center;justify-content:center;gap:8px;min-height:44px;padding:10px 14px;border:1px solid #073b4b40;border-radius:var(--radius-pill);background:none;font:400 clamp(.625rem,2.8vw,.6875rem)/1.5 var(--font-body)}
.sound-welcome button[data-sound-choice="on"]{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.sound-welcome svg{flex:none;width:16px;height:16px}
.sound-welcome button:focus-visible{outline:3px solid var(--sun);outline-offset:3px}
@media(max-width:360px){.sound-welcome-paper{padding:26px 22px}.sound-welcome-actions{gap:8px}.sound-welcome button{gap:6px;padding-inline:6px}}

.lesson-card[hidden],.accessory-slot[hidden]{display:none}

/* Near-viewport material loading keeps full section sizes for native scroll/GSAP. */
html.media-deferred [data-defer-media]:not([data-media-ready]),
html.media-deferred [data-defer-media]:not([data-media-ready]) *,
html.media-deferred [data-defer-media]:not([data-media-ready])::before,
html.media-deferred [data-defer-media]:not([data-media-ready])::after,
html.media-deferred [data-defer-media]:not([data-media-ready]) *::before,
html.media-deferred [data-defer-media]:not([data-media-ready]) *::after{background-image:none!important}
