/* Port Intro - cinematic night-harbour preloader (js/port-intro.js).
   Stage state lives on .port-intro[data-stage] plus .is-active / .is-done on each
   [data-station] and [data-ms]; everything below reads from those. */

html.port-intro-pending {
    background: #2b0b0f;
}

html.port-intro-pending body {
    overflow: hidden;
}

html.port-intro-pending body > *:not(.port-intro) {
    visibility: hidden;
}

.port-intro {
    --ph-ink: #f1e4d6;
    --ph-muted: #a88a80;
    --ph-dim: #6b4a44;
    --ph-amber: #f2a04c;
    --ph-gold: #ffd36a;
    --ph-structure: #2a1013;
    --ph-structure-hi: #3a1a1a;
    --ph-mono: "JetBrains Mono", "SFMono-Regular", Menlo, Consolas, monospace;

    position: fixed;
    inset: 0;
    z-index: 10050;
    display: grid;
    place-items: center;
    overflow: hidden;
    /* sky above the scene, water below it: the SVG covers the seam */
    background: linear-gradient(#2b0b0f 50%, #12040a 50%);
    color: var(--ph-ink);
    font-family: "Plus Jakarta Sans", system-ui, sans-serif;
    transition: opacity 0.7s ease;
}

.port-intro.is-leaving {
    opacity: 0;
    pointer-events: none;
}

.port-intro.is-paused *,
.port-intro.is-paused *::before {
    animation-play-state: paused !important;
}

/* ---- chrome --------------------------------------------------------------- */

.ph-header {
    position: absolute;
    top: 0;
    inset-inline: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: clamp(1rem, 3vw, 2rem) clamp(1rem, 4vw, 3rem);
}

.ph-brand {
    font-family: var(--ph-mono);
    font-size: 0.75rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--ph-muted);
}

.ph-skip,
.ph-btn {
    padding: 0.5rem 1rem;
    border: 1px solid rgba(241, 228, 214, 0.22);
    border-radius: 999px;
    background: rgba(18, 4, 10, 0.35);
    color: var(--ph-ink);
    font: 500 0.82rem/1 var(--ph-mono);
    cursor: pointer;
    transition: border-color 0.2s ease, color 0.2s ease, background-color 0.2s ease;
}

.ph-skip:hover,
.ph-skip:focus-visible,
.ph-btn:hover,
.ph-btn:focus-visible {
    border-color: var(--ph-amber);
    color: var(--ph-amber);
    outline: none;
}

.ph-btn--primary {
    border-color: var(--ph-amber);
    background: var(--ph-amber);
    color: #2b0b0f;
}

.ph-btn--primary:hover,
.ph-btn--primary:focus-visible {
    background: var(--ph-gold);
    color: #2b0b0f;
}

.ph-copy {
    position: absolute;
    top: clamp(4.5rem, 12vh, 8rem);
    inset-inline: 1rem;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
    text-align: center;
    animation: ph-rise 0.9s ease 0.2s both;
}

.ph-eyebrow {
    margin: 0;
    font-family: var(--ph-mono);
    font-size: 0.72rem;
    letter-spacing: 0.32em;
    text-transform: uppercase;
    color: var(--ph-amber);
}

.ph-headline {
    margin: 0;
    font-size: clamp(1.1rem, 2.4vw, 1.75rem);
    font-weight: 500;
    letter-spacing: -0.01em;
    color: var(--ph-ink);
}

.port-intro[data-stage="6"] .ph-headline { color: var(--ph-gold); }

.ph-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.ph-notice {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.6rem 0.8rem;
    margin-top: 0.4rem;
    font-size: 0.9rem;
    color: var(--ph-muted);
}

.ph-notice[hidden] { display: none; }

/* ---- scene frame ---------------------------------------------------------- */

.ph-scene {
    display: block;
    width: 100%;
    max-height: 100dvh;
}

.ph-world {
    transition: transform 0.7s cubic-bezier(0.45, 0, 0.2, 1);
}

/* Phase A: layers rise in from back to front */
.ph-layer {
    animation: ph-rise 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both;
    animation-delay: calc(var(--i, 0) * 70ms);
}

/* ---- palette for scene parts ---------------------------------------------- */

.ph-stars { fill: #f6dcc0; }
.ph-cloud { fill: #3d1215; opacity: 0.85; }
.ph-cloud--lit { fill: #5a1d1a; }
.ph-city-back { fill: #4a1a1a; opacity: 0.7; }
.ph-bldg { fill: #2a0d11; }
.ph-cwin { fill: #f3a64f; opacity: 0.85; }
.ph-cwin--rise { fill: var(--ph-gold); opacity: 0.12; transition: opacity 0.5s ease var(--d, 0ms); }
.ph-bridge path:first-child, .ph-bridge rect { fill: #24090e; }
.ph-bridge-cable { fill: none; stroke: #6b2a22; stroke-width: 1.4; }
.ph-bridge-lights { fill: var(--ph-amber); }
.ph-beacon { fill: #ff6a4d; animation: ph-blink 2.4s ease-in-out infinite; }
.ph-shimmer rect { fill: var(--ph-amber); opacity: 0.12; animation: ph-shimmer 3.2s ease-in-out infinite alternate; animation-delay: var(--d, 0s); }
.ph-streak { transform-box: fill-box; transform-origin: top; animation: ph-ripple 2.6s ease-in-out infinite alternate; animation-delay: var(--d, 0s); }

.ph-pier-shadow { fill: #1a070b; }
.ph-braces { fill: none; stroke: #2e1214; stroke-width: 2; }
.ph-pilings { fill: #200a0d; }
.ph-deck { fill: #3a1a16; }
.ph-deck-edge { fill: #a2603a; opacity: 0.7; }
.ph-bulb { fill: #ffe0a6; }
.ph-pulse { animation: ph-pulse 3.4s ease-in-out infinite alternate; animation-delay: var(--d, 0s); transform-box: fill-box; transform-origin: center; }
.ph-post { fill: none; stroke: #4a2420; stroke-width: 2.2; stroke-linecap: round; }

.ph-structure { fill: var(--ph-structure); }
.ph-crane .ph-structure { fill: #4a2219; }
.ph-roof { fill: none; stroke: #4e2420; stroke-width: 5; stroke-linecap: round; }
.ph-rim { fill: none; stroke: var(--ph-amber); stroke-width: 1.2; opacity: 0.35; }
.ph-truss { fill: none; stroke: #7a3a2a; stroke-width: 2; stroke-linecap: round; }
.ph-crate { fill: #d0773a; stroke: #7a3a1c; stroke-width: 1; }
.ph-crate--dark { fill: #5a2a20; stroke: #3a1712; }
.ph-box { stroke: rgba(0, 0, 0, 0.25); stroke-width: 1; }
.ph-box--orange { fill: #c9642c; }
.ph-ridges { stroke: rgba(0, 0, 0, 0.22); stroke-width: 1.4; }
.ph-machine { fill: #c27a2c; }
.ph-machine-accent { fill: #8a4a1e; }
.ph-wheel { fill: #1a0a0b; stroke: #4a2420; stroke-width: 1.5; }
.ph-person { fill: #2a1416; }
.ph-skin { fill: #d9a07a; }
.ph-vest { fill: #e07a2c; }
.ph-hat { fill: #f1e4d6; }
.ph-tablet { fill: #ffd38a; opacity: 0.5; transition: opacity 0.3s ease; }

.ph-interior { opacity: 0.88; }
.ph-shutter { fill: #4a2420; }
.ph-status-light { fill: var(--ph-dim); transition: fill 0.3s ease; }
.ph-scan { fill: var(--ph-gold); opacity: 0; }

.ph-cab-light { fill: var(--ph-dim); transition: fill 0.3s ease; }
.ph-cable { fill: none; stroke: #5a2c24; stroke-width: 1.5; }
.ph-hook-shape { fill: none; stroke: #5a2c24; stroke-width: 1.5; }
/* the load hangs from the trolley: sway pivots there, lowering moves the hook */
.ph-sway { animation: ph-sway 4.2s ease-in-out infinite alternate; }
.ph-hook, .ph-cable--load { transition: transform 0.9s cubic-bezier(0.45, 0, 0.2, 1); }

.ph-door-panel { fill: #3a1a18; }
.ph-shield-body { fill: none; stroke: var(--ph-amber); stroke-width: 1.4; opacity: 0.55; transition: opacity 0.3s ease, stroke 0.3s ease; }
.ph-shield-check { fill: none; stroke: var(--ph-gold); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 0.45s ease; }
.ph-pole { fill: #e8d8c8; }
.ph-pole-stripes { stroke: #c0402f; stroke-width: 8; }

.ph-rock { fill: #3a1412; }
.ph-rock-rim { fill: none; stroke: #b0552c; stroke-width: 1.4; opacity: 0.5; }
.ph-tower { fill: #e6d6c4; }
.ph-stripe { fill: #c23f33; }
.ph-tower-shade { fill: #000; opacity: 0.18; }
.ph-railing { fill: none; stroke: #4a2420; stroke-width: 1.2; }
.ph-lantern { fill: #ffd38a; }
/* beam rotates around the lantern: scaleX sweeps it across like a turning lens */
.ph-beam { opacity: 0.55; animation: ph-sweep 9s linear infinite; transition: opacity 0.6s ease; }
.ph-lantern-glow { animation: ph-flare 9s linear infinite; transform-box: fill-box; transform-origin: center; }
.ph-glint { fill: var(--ph-amber); opacity: 0; }
.ph-glint--r { animation: ph-glint 9s linear infinite; }
.ph-glint--l { animation: ph-glint 9s linear infinite -4.5s; }

.ph-ship { animation: ph-bob 5s ease-in-out infinite alternate; }
.ph-ship-reflect { fill: #000; opacity: 0.35; }
.ph-superstructure { fill: #d8cbbd; }
.ph-bridge-windows { stroke: #3a2a2a; stroke-width: 4; }
.ph-hull { fill: #1b2230; }
.ph-hull-band { fill: #8a2a22; }
.ph-portholes { stroke: #ffd38a; stroke-width: 2; }
.ph-wake { fill: none; stroke: var(--ph-amber); stroke-width: 1.4; opacity: 0.45; }

/* ---- stage states --------------------------------------------------------- */

/* DOCK: forklift rolls forward, an activity ring pulses */
.ph-forklift { transition: transform 1.2s cubic-bezier(0.45, 0, 0.2, 1); }
.ph-dock.is-active .ph-forklift,
.ph-dock.is-done .ph-forklift { transform: translateX(16px); }
.ph-ring { fill: none; stroke: var(--ph-amber); stroke-width: 1.4; opacity: 0; transform-box: fill-box; transform-origin: center; }
.ph-dock.is-active .ph-ring { animation: ph-ring 1.1s ease-out infinite; }

/* INSPECTION: one restrained scan line passes through the lit warehouse */
.ph-inspect.is-active .ph-scan { animation: ph-scan-down 0.9s ease-in-out infinite alternate; }
.ph-inspect.is-active .ph-status-light { fill: var(--ph-amber); }
.ph-inspect.is-done .ph-status-light { fill: var(--ph-gold); }

/* CRANE: cab lights up, cable pays out and the container lowers a few pixels */
.ph-crane:is(.is-active, .is-done) .ph-cab-light { fill: var(--ph-amber); }
.ph-crane:is(.is-active, .is-done) .ph-hook { transform: translateY(10px); }
.ph-crane:is(.is-active, .is-done) .ph-cable--load { transform: scaleY(1.154); transform-box: fill-box; transform-origin: top; }

/* CUSTOMS: scan across the door, then the shield seal is checked */
.ph-customs.is-active .ph-scan--v { animation: ph-scan-across 0.8s ease-in-out infinite alternate; }
.ph-customs:is(.is-active, .is-done) .ph-tablet { opacity: 1; }
.ph-customs:is(.is-active, .is-done) .ph-shield-body { opacity: 1; stroke: var(--ph-gold); }
.ph-customs.is-done .ph-shield-check { stroke-dashoffset: 0; }

/* LIGHTHOUSE: beam brightens while monitoring */
.ph-lighthouse:is(.is-active, .is-done) .ph-beam { opacity: 1; }

/* CITY: more windows come on once production is live */
.ph-city.is-done .ph-cwin--rise { opacity: 1; }

/* ---- milestone rail ------------------------------------------------------- */

.ph-track { stroke: #6b3a2e; stroke-width: 1.6; opacity: 0.8; }
.ph-fill {
    stroke-width: 2.4;
    stroke-linecap: round;
    transform: scaleX(0);
    transform-box: fill-box;
    transform-origin: left;
    transition: transform 0.45s cubic-bezier(0.45, 0, 0.2, 1);
}
.ph-head { opacity: 0; transition: transform 0.45s cubic-bezier(0.45, 0, 0.2, 1), opacity 0.3s ease; }
.port-intro:not([data-stage="0"]) .ph-head { opacity: 1; }
.port-intro[data-stage="6"] .ph-head { opacity: 0; }

.ph-ms-label,
.ph-ms-sub {
    font-family: var(--ph-mono);
    text-anchor: middle;
    transition: fill 0.35s ease;
}
.ph-ms-label { font-size: 17px; font-weight: 700; letter-spacing: 2px; fill: #9c7d74; }
.ph-ms-sub { font-size: 14px; fill: #7a5e57; }
.ph-node { fill: #4a2620; stroke: #8a5a48; stroke-width: 1.4; transition: fill 0.3s ease, stroke 0.3s ease; }

.ph-ms.is-active .ph-ms-label { fill: var(--ph-amber); }
.ph-ms.is-active .ph-ms-sub { fill: #d9a27a; }
.ph-ms.is-active .ph-node { fill: var(--ph-amber); stroke: var(--ph-amber); }
.ph-ms.is-done .ph-ms-label { fill: var(--ph-ink); }
.ph-ms.is-done .ph-node { fill: #e6c9a8; stroke: #e6c9a8; }
.ph-ms[data-ms="5"].is-done .ph-ms-label,
.ph-ms[data-ms="5"].is-done .ph-ms-sub { fill: var(--ph-gold); }
.ph-ms[data-ms="5"].is-done .ph-node { fill: var(--ph-gold); stroke: var(--ph-gold); r: 6.5; }

.port-intro.is-failed .ph-ms.is-active .ph-node { fill: #e2553a; stroke: #e2553a; }

/* compact rail for phones */
.ph-compact { display: none; }

/* ---- responsive ----------------------------------------------------------- */

@media (max-width: 1100px) {
    .ph-ms-sub { font-size: 16px; }
    .ph-ms-label { font-size: 19px; }
}

/* phones and portrait tablets (.is-mobile is set by the camera logic) */
.port-intro.is-mobile { background: linear-gradient(#2b0b0f 45%, #12040a 45%); }
.port-intro.is-mobile .ph-rail { display: none; }
.port-intro.is-mobile .ph-compact {
    position: absolute;
    bottom: max(2rem, 7vh);
    inset-inline: 1.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.9rem;
}
.port-intro.is-mobile .ph-compact ol {
    position: relative;
    display: flex;
    justify-content: space-between;
    width: min(100%, 320px);
    margin: 0;
    padding: 0;
    list-style: none;
}
.port-intro.is-mobile .ph-compact ol::before {
    content: "";
    position: absolute;
    inset-inline: 4px;
    top: 50%;
    height: 1px;
    background: #6b3a2e;
}
.port-intro.is-mobile .ph-dot {
    position: relative;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #4a2620;
    border: 1px solid #8a5a48;
    transition: background-color 0.3s ease, border-color 0.3s ease;
}
.port-intro.is-mobile .ph-dot.is-done { background: #e6c9a8; border-color: #e6c9a8; }
.port-intro.is-mobile .ph-dot.is-active { background: var(--ph-amber); border-color: var(--ph-amber); }
.port-intro.is-mobile .ph-dot[data-ms="5"].is-done { background: var(--ph-gold); border-color: var(--ph-gold); }
.port-intro.is-mobile .ph-compact p {
    margin: 0;
    font: 600 0.8rem/1.4 var(--ph-mono);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ph-amber);
}
.port-intro.is-mobile[data-stage="6"] .ph-compact p { color: var(--ph-gold); }

@media (max-width: 700px) {
    .ph-brand { font-size: 0.65rem; letter-spacing: 0.16em; }
    .ph-copy { top: 4.5rem; }
}

/* ---- reduced motion: keep the scene and the progress, drop the movement ---- */

.port-intro.is-calm *,
.port-intro.is-calm *::before {
    animation: none !important;
    transition-property: opacity, fill, stroke, color, background-color, border-color !important;
}

.port-intro.is-calm .ph-beam { opacity: 0.8; }

/* ---- keyframes ------------------------------------------------------------ */

@keyframes ph-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes ph-twinkle { 50% { opacity: 0.2; } }
@keyframes ph-blink { 50% { opacity: 0.25; } }
@keyframes ph-shimmer { from { opacity: 0.04; transform: translateX(-4px); } to { opacity: 0.22; transform: translateX(4px); } }
@keyframes ph-ripple { from { transform: scaleX(0.7); opacity: 0.7; } to { transform: scaleX(1.25); opacity: 1; } }
@keyframes ph-pulse { from { opacity: 0.65; } to { opacity: 1; } }
@keyframes ph-sway { from { transform: rotate(-1.1deg); } to { transform: rotate(1.1deg); } }
@keyframes ph-ring { from { opacity: 0.7; transform: scale(0.6); } to { opacity: 0; transform: scale(1.6); } }
@keyframes ph-scan-down { from { transform: translateY(0); } to { transform: translateY(60px); } }
@keyframes ph-scan-across { from { transform: translateX(0); } to { transform: translateX(28px); } }
@keyframes ph-sweep {
    0% { transform: rotate(-6deg) scaleX(1); }
    25% { transform: rotate(-6deg) scaleX(0.04); }
    50% { transform: rotate(-6deg) scaleX(-1); }
    75% { transform: rotate(-6deg) scaleX(0.04); }
    100% { transform: rotate(-6deg) scaleX(1); }
}
@keyframes ph-flare { 0%, 50%, 100% { opacity: 0.7; } 25% { opacity: 1; transform: scale(1.25); } 75% { opacity: 0.45; } }
@keyframes ph-glint { 0% { opacity: 0.35; } 20%, 80% { opacity: 0; } 100% { opacity: 0.35; } }
@keyframes ph-bob { from { transform: translateY(0); } to { transform: translateY(1.6px); } }

.ph-stars .ph-twinkle { animation: ph-twinkle 3.6s ease-in-out infinite; animation-delay: var(--d, 0s); }
