Spaces:
Running
Running
File size: 29,230 Bytes
fcce7e3 84bc42a fcce7e3 84bc42a 369b236 84bc42a 369b236 84bc42a fcce7e3 369b236 fcce7e3 369b236 fcce7e3 bebd577 fcce7e3 369b236 fcce7e3 369b236 fcce7e3 6468c17 fcce7e3 b51e03a 505c280 b51e03a 369b236 181ede2 369b236 6468c17 369b236 181ede2 6468c17 b51e03a 369b236 6468c17 369b236 6468c17 369b236 6468c17 369b236 6468c17 84bc42a 6468c17 369b236 fcce7e3 369b236 fcce7e3 bebd577 369b236 fcce7e3 c782e5b 3597f5a 505c280 3597f5a 505c280 3597f5a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | /* ============================================================================
TUTORIAL — KEEL, ship liaison intelligence
----------------------------------------------------------------------------
Visual family: same panel gradient, same border-image trick, same type
ramp as the rest of the HUD (--panelG2, --fT/--fU, the bevelled border
gradients in src/styles/ui.css's :root) — those custom properties cascade
from :root regardless of which stylesheet declared them, so reusing them
here keeps KEEL native to the HUD instead of a decal stuck on top of it.
KEEL gets its own accent (cyan, --keelB below) so its panel reads as its
own character rather than a reskinned dispatch or coach banner.
Placement: docked centre, below the goal/hero/hive cluster (ends ~105px
from the safe-area top once deployed) and below the native #toast's usual
footprint (up to ~190px for a three-line message), so KEEL's line and a
stock toast very rarely fight for the same pixels. Verified empirically
against 412×900 screenshots — see docs/TUTORIAL.md.
============================================================================ */
:root{
--keelB:linear-gradient(160deg,#bdeeff 0%,#6fd0ff 26%,#0c3a52 58%,#1a6f99 80%,#bdeeff 100%);
}
/* ============================================================================
NEW-CAREER ORIENTATION
----------------------------------------------------------------------------
One calm decision surface over the approach view: arrival, optional basics,
required faction commissioning, then Commander 1. It is intentionally not
attached to START or the War Table, so the current main menu stays intact.
============================================================================ */
body.mfOnboardingOpen{overflow:hidden}
#mfOnboardingChoice{
position:fixed;inset:0;z-index:2200;display:grid;place-items:center;overflow:auto;
padding:max(12px,calc(var(--sat,0px) + 8px)) max(10px,env(safe-area-inset-right)) max(12px,calc(var(--sab,0px) + 8px)) max(10px,env(safe-area-inset-left));
box-sizing:border-box;color:#eefaff;font-family:var(--fU,system-ui,sans-serif);
background:radial-gradient(circle at 72% 22%,rgba(68,164,204,.20),transparent 30%),linear-gradient(180deg,rgba(1,7,13,.92),rgba(2,10,16,.985));
}
#mfOnboardingChoice[hidden]{display:none!important}
.mfOnboardingFrame{
width:min(1120px,100%);min-height:min(760px,calc(100dvh - 28px));display:grid;grid-template-columns:minmax(280px,.78fr) minmax(520px,1.22fr);
overflow:hidden;border:1px solid rgba(105,211,247,.35);border-radius:22px;
background:#06121b;box-shadow:0 34px 110px rgba(0,0,0,.86),0 0 65px rgba(67,191,235,.10);
}
#mfOnboardingChoice[data-flow="default"] .mfOnboardingFrame{grid-template-columns:minmax(0,760px);min-height:0;width:min(760px,100%)}
#mfOnboardingChoice[data-flow="default"] .mfOnboardingScene{display:none}
.mfOnboardingScene{
position:relative;min-height:360px;overflow:hidden;padding:22px;
background:
radial-gradient(circle at 18% 17%,#dffaff 0 1px,transparent 2px),radial-gradient(circle at 76% 28%,#8ceaff 0 1px,transparent 2px),
radial-gradient(circle at 31% 62%,#9ed9ed 0 1px,transparent 2px),radial-gradient(circle at 88% 73%,#fff 0 1px,transparent 2px),
linear-gradient(150deg,#061626,#02070c 68%);
}
.mfOnboardingScene::before{content:"";position:absolute;inset:0;opacity:.26;background-image:linear-gradient(rgba(96,206,244,.08) 1px,transparent 1px),linear-gradient(90deg,rgba(96,206,244,.06) 1px,transparent 1px);background-size:42px 42px;mask-image:linear-gradient(to bottom,black,transparent 88%)}
.mfOnboardingPlanet{position:absolute;left:15%;bottom:-9%;width:112%;aspect-ratio:1;border-radius:50%;background:radial-gradient(circle at 38% 31%,#c5e5e4 0 3%,#548aa1 19%,#203e56 45%,#071522 69%);box-shadow:-28px -22px 76px rgba(83,216,255,.24),0 0 0 2px rgba(141,230,255,.16)}
.mfOnboardingPlanet::after{content:"";position:absolute;inset:-2%;border-radius:50%;border-top:2px solid rgba(162,238,255,.7);filter:blur(1px)}
.mfOnboardingMoon{position:absolute;right:13%;top:20%;width:38px;height:38px;border-radius:50%;background:radial-gradient(circle at 38% 33%,#d5edf0,#506a76 72%);box-shadow:0 0 18px rgba(137,223,246,.15)}
.mfOnboardingVector{position:absolute;left:20%;top:25%;width:56%;height:46%;border-top:1px solid rgba(101,225,255,.52);border-right:1px solid rgba(101,225,255,.3);transform:skew(-28deg) rotate(13deg)}
.mfOnboardingVector::before{content:"";position:absolute;right:-5px;top:-5px;width:9px;height:9px;border:1px solid #95edff;background:#0a2736;transform:rotate(45deg);box-shadow:0 0 14px #5fe1ff}
.mfOnboardingScene>b,.mfOnboardingScene>i{position:relative;z-index:2;display:block;font-family:var(--fT,system-ui);font-style:normal;letter-spacing:.15em}
.mfOnboardingScene>b{color:#a9efff;font-size:10px}.mfOnboardingScene>i{margin-top:6px;color:#638797;font-size:8px}
.mfOnboardingCard{min-width:0;background:linear-gradient(155deg,rgba(10,29,42,.99),rgba(3,12,19,.995) 62%)}
.mfOnboardingHeader{display:flex;align-items:center;gap:12px;min-height:66px;padding:11px clamp(15px,3vw,28px);border-bottom:1px solid rgba(105,211,247,.18);background:rgba(7,24,34,.82)}
.mfOnboardingKeel{position:relative;display:grid;place-items:center;width:40px;height:40px;flex:0 0 40px;border:1px solid rgba(105,224,255,.58);border-radius:50%;color:#c5f6ff;background:radial-gradient(circle,rgba(80,218,255,.22),transparent 68%);font:900 17px/1 var(--fT);box-shadow:0 0 17px rgba(73,213,255,.13)}
.mfOnboardingHeader>span:last-child b,.mfOnboardingHeader>span:last-child small{display:block}.mfOnboardingHeader>span:last-child b{color:#baf3ff;font:900 12px/1 var(--fT);letter-spacing:.16em}.mfOnboardingHeader>span:last-child small{margin-top:5px;color:#7897a6;font:800 8px/1.2 var(--fT);letter-spacing:.12em}
.mfOnboardingPath{display:grid;grid-template-columns:repeat(4,1fr);border-bottom:1px solid rgba(105,211,247,.14)}
.mfOnboardingPath>span{position:relative;display:flex;align-items:center;justify-content:center;gap:6px;min-height:42px;padding:6px 4px;color:#58717e;font:800 7px/1.2 var(--fT);letter-spacing:.08em;text-align:center}.mfOnboardingPath>span:not(:last-child)::after{content:"";position:absolute;right:0;width:1px;height:18px;background:rgba(112,206,235,.13)}
.mfOnboardingPath b{display:grid;place-items:center;width:19px;height:19px;border:1px solid #435e6a;border-radius:50%;font-size:7px}.mfOnboardingPath .done{color:#81a4b2}.mfOnboardingPath .done b{color:#8be8ff;border-color:#55b9d7}.mfOnboardingPath .on{color:#e6faff;background:linear-gradient(90deg,rgba(60,190,232,.11),transparent)}.mfOnboardingPath .on b{color:#eaffff;border-color:#70e3ff;background:#16495e;box-shadow:0 0 12px rgba(87,220,255,.2)}
.mfOnboardingCard>main{padding:clamp(20px,3.5vw,35px)}
.mfOnboardingEyebrow{color:#68dcff;font:900 9px/1.2 var(--fT);letter-spacing:.19em}.mfOnboardingCard h2{max-width:680px;margin:8px 0 8px;font:900 clamp(27px,4.5vw,48px)/1 var(--fT);letter-spacing:.012em}.mfOnboardingLead{max-width:690px;margin:0;color:#a7bdc8;font:600 11px/1.55 var(--fU)}
.mfOnboardingTracks{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:20px 0 12px}.mfOnboardingTrack{min-width:0;padding:13px;border:1px solid rgba(104,186,217,.22);border-radius:11px;background:rgba(10,32,45,.63)}.mfOnboardingTrack.recommended{border-color:rgba(91,218,255,.48);background:linear-gradient(150deg,rgba(31,105,132,.30),rgba(7,28,40,.78))}.mfOnboardingTrack small,.mfOnboardingTrack b,.mfOnboardingTrack span{display:block}.mfOnboardingTrack small{color:#6ddfff;font:900 7px/1 var(--fT);letter-spacing:.14em}.mfOnboardingTrack b{margin-top:7px;color:#e9faff;font:900 12px/1.2 var(--fT);letter-spacing:.035em}.mfOnboardingTrack span{margin-top:6px;color:#91aab7;font:600 9px/1.45 var(--fU)}
.mfOnboardingSteps{display:flex;flex-wrap:wrap;gap:5px;margin:0 0 18px}.mfOnboardingSteps span{padding:5px 7px;border:1px solid rgba(91,198,232,.24);border-radius:999px;color:#9bc8d8;background:rgba(22,74,93,.16);font:800 7px/1 var(--fT);letter-spacing:.06em}
.mfOnboardingActions{display:grid;grid-template-columns:1.15fr 1fr;gap:9px}.mfOnboardingActions button{display:flex;flex-direction:column;align-items:flex-start;justify-content:center;min-height:58px;padding:10px 14px;border:1px solid #6ce2ff;border-radius:9px;color:white;background:linear-gradient(180deg,#187a9d,#0c435b);box-shadow:inset 0 1px rgba(255,255,255,.12),0 7px 20px rgba(0,0,0,.28);font:900 10px/1.2 var(--fT);letter-spacing:.075em;text-align:left;touch-action:manipulation}.mfOnboardingActions button small{display:block;margin-bottom:5px;color:#a9edff;font-size:7px;letter-spacing:.14em}.mfOnboardingActions .quiet{border-color:#385765;color:#b8ccd5;background:#081923;box-shadow:none}.mfOnboardingActions .quiet small{color:#6f8d99}.mfOnboardingActions button:focus-visible{outline:2px solid #d7f8ff;outline-offset:3px}.mfOnboardingActions button:active{transform:translateY(1px);filter:brightness(1.15)}
.mfOnboardingFoot{margin:12px 2px 0;color:#708996;font:700 8px/1.45 var(--fU);text-align:center}
@media(max-width:860px){.mfOnboardingFrame{grid-template-columns:1fr;min-height:0}.mfOnboardingScene{min-height:190px}.mfOnboardingPlanet{left:35%;bottom:-115%;width:90%}.mfOnboardingMoon{top:18%;right:18%}.mfOnboardingVector{left:35%;top:30%;width:43%;height:55%}}
@media(max-width:540px){#mfOnboardingChoice{place-items:start center}.mfOnboardingFrame{border-radius:15px}.mfOnboardingScene{min-height:132px;padding:14px}.mfOnboardingPlanet{left:39%;bottom:-150%;width:92%}.mfOnboardingMoon{width:25px;height:25px}.mfOnboardingHeader{min-height:58px;padding:9px 13px}.mfOnboardingKeel{width:36px;height:36px;flex-basis:36px}.mfOnboardingHeader>span:last-child small{font-size:7px}.mfOnboardingPath>span{font-size:0;min-height:38px}.mfOnboardingPath b{font-size:7px}.mfOnboardingCard>main{padding:19px 14px 15px}.mfOnboardingCard h2{font-size:30px}.mfOnboardingTracks,.mfOnboardingActions{grid-template-columns:1fr}.mfOnboardingTracks{gap:7px;margin-top:15px}.mfOnboardingTrack{padding:11px}.mfOnboardingSteps{margin-bottom:14px}.mfOnboardingActions button{min-height:60px}.mfOnboardingFoot{text-align:left}}
@media(prefers-reduced-motion:reduce){.mfOnboardingActions button:active{transform:none}}
#keelWrap{
position:absolute; left:50%; top:calc(var(--sat) + 204px);
transform:translateX(-50%);
width:min(90vw,380px);
z-index:19; /* level with #coach — both are HUD-native narration, neither an overlay */
pointer-events:none;
opacity:0; visibility:hidden;
transition:opacity .28s ease;
}
#keelWrap.show{ opacity:1; visibility:visible; pointer-events:none; }
#keelWrap.show #keelBar{ pointer-events:auto; }
#keelBar{
display:flex; align-items:flex-start; gap:9px;
border-radius:12px; padding:9px 10px 9px 9px;
border:1px solid transparent;
background:var(--panelG2) padding-box, var(--keelB) border-box;
box-shadow:0 6px 20px rgba(0,0,0,.55);
transition:opacity .3s ease, transform .2s ease;
}
#keelBar.resting{ opacity:.82; transform:scale(.99); }
#keelBar.pulse{ animation:keelPulse .5s cubic-bezier(.2,.8,.3,1); }
@keyframes keelPulse{
0%{ transform:scale(.96); box-shadow:0 6px 20px rgba(0,0,0,.55), 0 0 0 0 rgba(120,220,255,.5); }
60%{ transform:scale(1.015); }
100%{ transform:scale(1); box-shadow:0 6px 20px rgba(0,0,0,.55), 0 0 0 8px rgba(120,220,255,0); }
}
/* ---------- KEEL: neutral UGA signal identity, never a faction portrait ---- */
#keelBadge{ position:relative; width:42px; height:42px; flex:0 0 42px; margin-top:1px;
display:grid;place-items:center;border-radius:9px;background:radial-gradient(circle at 50% 46%,rgba(79,218,255,.22),transparent 58%),linear-gradient(145deg,#0b2a3a,#030b12);
border:1px solid rgba(120,220,255,.78);box-shadow:0 0 12px rgba(70,190,245,.24);overflow:hidden; }
#keelBadge::before{content:'K';position:relative;z-index:2;color:#bcefff;font:900 17px/1 var(--fT);letter-spacing:.04em;text-shadow:0 0 8px rgba(80,220,255,.8)}
#keelBadge::after{content:'UGA';position:absolute;z-index:3;left:0;right:0;bottom:3px;color:#ffe079;font:900 5px/1 var(--fT);letter-spacing:.15em;text-align:center}
#keelBadge .kr{
position:absolute; inset:4px; border-radius:50%;
border:1.5px solid rgba(120,220,255,.55);
}
#keelBadge .kr2{ inset:10px; border-color:rgba(120,220,255,.85); }
#keelBadge .kd{
position:absolute; left:50%; top:50%; width:5px; height:5px; margin:-2.5px 0 0 -2.5px;
border-radius:50%; background:#bdeeff; box-shadow:0 0 6px 1px rgba(120,220,255,.9);
}
#keelBar.pulse #keelBadge .kr1{ animation:keelRing 1.1s ease-out; }
#keelBar.pulse #keelBadge .kr2{ animation:keelRing 1.1s .12s ease-out; }
@keyframes keelRing{
0%{ transform:scale(.6); opacity:1; }
100%{ transform:scale(1.7); opacity:0; }
}
#keelBody{ flex:1 1 auto; min-width:0; }
#keelHd{ display:flex; align-items:baseline; gap:7px; flex-wrap:wrap; }
#keelName{
font-family:var(--fT); font-size:11.5px; font-weight:800; letter-spacing:.14em;
color:#bdeeff; text-shadow:0 0 8px rgba(65,200,255,.5);
}
#keelStepTag{
font-family:var(--fT); font-size:9px; font-weight:700; letter-spacing:.1em;
color:#7fa8c6; text-transform:uppercase;
}
#keelTxt{
margin-top:2px; font-size:12.5px; line-height:1.36; font-weight:600; color:#eaf7ff;
}
#keelProgress{
height:3px;margin-top:7px;border-radius:4px;overflow:hidden;background:rgba(4,12,20,.78);
box-shadow:inset 0 0 0 1px rgba(120,205,242,.16);
}
#keelProgress i{
display:block;width:0;height:100%;border-radius:inherit;
background:linear-gradient(90deg,#42c9ff,#ffe06b);box-shadow:0 0 7px rgba(88,205,255,.62);
transition:width .3s ease;
}
#keelNext{
display:none;align-items:center;justify-content:center;min-width:92px;min-height:44px;margin-top:8px;padding:8px 15px;
border-radius:8px;border:1px solid rgba(255,218,112,.75);color:#171104;
background:linear-gradient(180deg,#fff0a8,#dca936);box-shadow:0 0 13px rgba(255,207,75,.28);
font:900 9px/1 var(--fT);letter-spacing:.13em;
}
#keelSkip{
flex:0 0 auto; align-self:flex-start;
/* Visual glyph is small; the tap target is not. 44px is the WCAG 2.5.5
floor — verified against the rendered box, not just the source, since
box-sizing elsewhere in this codebase can make padding eat into a
min-width instead of adding to it. */
min-width:52px; min-height:44px; margin:-9px -9px 0 0;
display:flex; align-items:center; justify-content:center;
border-radius:9px; border:none; background:transparent; color:#7fa8c6;
font:800 9px/1 var(--fT);letter-spacing:.08em;
box-sizing:border-box;
}
#keelSkip:active{ background:rgba(255,255,255,.08); color:#eaf7ff; }
/* Reactive dialogue stays available during battle, but yields most of its
height to the battlefield. The full line remains in the event feed and the
card expands again as soon as combat heat falls. */
body.mfCombatHot #keelBar{align-items:center;gap:6px;padding:5px 7px;border-radius:9px}
body.mfCombatHot #keelBadge{width:30px;height:30px;flex-basis:30px;margin:0}
body.mfCombatHot #keelHd{flex-wrap:nowrap}
body.mfCombatHot #keelName{font-size:9px}
body.mfCombatHot #keelStepTag{display:none}
body.mfCombatHot #keelTxt{margin:0;font-size:10px;line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
body.mfCombatHot #keelProgress,body.mfCombatHot #keelNext{display:none!important}
/* Keep the destructive END / SKIP control finger-sized even as the card
compacts during combat; shrinking only its visual copy saves the space. */
body.mfCombatHot #keelSkip{min-width:52px;min-height:44px;margin:-7px -7px -7px 0;font-size:8px}
/* The guided target never receives input. It only makes the existing hit box
visible, so the button/tab/card keeps its normal mobile interaction path. */
.keelFocus{
position:relative!important;z-index:22!important;
outline:4px solid #ffe06b!important;outline-offset:4px!important;
box-shadow:0 0 0 4px rgba(255,214,70,.30),0 0 30px 9px rgba(255,202,50,.82)!important;
animation:keelTarget 1.05s ease-in-out infinite!important;
}
@keyframes keelTarget{
0%,100%{filter:brightness(1);}
50%{filter:brightness(1.38);}
}
#keelMapCue{
position:fixed;left:50%;top:50%;width:82px;height:82px;transform:translate(-50%,-50%);z-index:21;
display:none;border:3px solid #ffe06b;border-radius:50%;pointer-events:none;box-sizing:border-box;
box-shadow:0 0 0 7px rgba(255,215,72,.15),0 0 26px rgba(255,204,55,.72);
animation:keelMapPulse 1.05s ease-in-out infinite;
}
#keelMapCue.show{display:block}
#keelMapCue::before,#keelMapCue::after{content:'';position:absolute;background:#ffe06b;opacity:.9}
#keelMapCue::before{width:2px;height:112px;left:37px;top:-18px}
#keelMapCue::after{height:2px;width:112px;left:-18px;top:37px}
#keelMapCue span{
position:absolute;left:50%;top:calc(100% + 10px);transform:translateX(-50%);min-width:108px;padding:5px 7px;
border-radius:7px;background:rgba(10,15,22,.94);border:1px solid rgba(255,224,107,.75);color:#ffe891;
text-align:center;white-space:nowrap;font:900 9px/1.2 var(--fT);letter-spacing:.08em;
}
#keelModeBadge{position:fixed;left:50%;top:calc(var(--sat) + 72px);transform:translateX(-50%);z-index:20;display:none;
min-width:188px;padding:7px 10px;border:1px solid rgba(255,224,107,.72);border-radius:9px;text-align:center;
background:linear-gradient(135deg,rgba(51,37,9,.96),rgba(8,21,31,.95));box-shadow:0 5px 18px rgba(0,0,0,.42),0 0 16px rgba(255,208,67,.16);pointer-events:none}
#keelModeBadge.show{display:block}#keelModeBadge b,#keelModeBadge span{display:block;font-family:var(--fT);letter-spacing:.1em}#keelModeBadge b{color:#ffe792;font-size:9px}#keelModeBadge span{margin-top:3px;color:#a9d7ef;font-size:9px;font-weight:800}
/* One coaching surface on a phone. STEP/TOTAL already lives in #keelBar, and
ordinary command notices remain recorded in the notification log. Showing
both duplicates above/below KEEL produced three stacked panels before the
player could even see the unit being discussed. Emergency attack/wave rails
are separate and remain available. */
body.trainingOperation #keelModeBadge,body.trainingOperation #toast{display:none!important}
@keyframes keelMapPulse{0%,100%{transform:translate(-50%,-50%) scale(.92)}50%{transform:translate(-50%,-50%) scale(1.06)}}
/* First-time entry point. PLAY remains a normal skirmish; this explicit card
launches the fixed, protected training ruleset. */
#keelTrainingCallout{
width:min(88vw,360px);box-sizing:border-box;margin:15px auto 0;padding:9px;border-radius:12px;text-align:left;
display:flex;align-items:center;gap:9px;
border:1px solid rgba(255,216,86,.52);background:linear-gradient(180deg,rgba(43,35,15,.94),rgba(13,20,29,.97));
box-shadow:0 5px 18px rgba(0,0,0,.42),0 0 18px rgba(255,202,55,.1);
}
.ktMiniIdentity{display:flex;align-items:center;gap:8px;flex:1;min-width:0}.ktMiniIdentity>img{width:38px;height:38px;object-fit:contain;flex:0 0 38px}
.ktMiniIdentity>div{min-width:0}.ktMiniIdentity span,.ktMiniIdentity small{display:block;color:#ffe079;font:900 9px/1.1 var(--fT);letter-spacing:.12em}
.ktMiniIdentity b{display:block;margin:3px 0;color:#fff;font:900 10px/1.1 var(--fT);letter-spacing:.06em}.ktMiniIdentity small{color:#83a5bd;letter-spacing:.08em}
#keelTrainingCallout>button{
flex:0 0 98px;min-width:98px;min-height:48px;padding:8px;border-radius:8px;border:1px solid #ffe79a;color:#181203;
background:linear-gradient(180deg,#fff1a8,#dda837);font:900 9px/1 var(--fT);letter-spacing:.07em;
}
#keelTrainingCallout+#startBtn{margin-top:10px!important}
.keelTrainingOp{
--ktoAccent:#ffe079;position:relative;margin:0 0 13px;padding:0 12px 12px;border-radius:14px;text-align:left;overflow:hidden;
border:1px solid rgba(255,215,80,.56);background:linear-gradient(155deg,rgba(53,39,11,.92),rgba(13,21,31,.98) 48%,rgba(8,27,40,.98));
box-shadow:0 8px 22px rgba(0,0,0,.35),inset 0 1px rgba(255,255,255,.04);
}
.keelTrainingOp::after{content:'';position:absolute;right:-65px;top:42px;width:210px;height:210px;border-radius:50%;pointer-events:none;background:radial-gradient(circle,rgba(75,194,255,.12),transparent 67%)}
.keelTrainingOp.done{--ktoAccent:#8bf0b7;border-color:rgba(104,237,166,.48);background:linear-gradient(155deg,rgba(18,54,40,.82),rgba(10,23,27,.98) 52%,rgba(8,28,39,.98))}
.keelTrainingOp.active{--ktoAccent:#76ddff;border-color:rgba(89,211,255,.68)}
.ktoHead{height:38px;margin:0 -12px 10px;padding:0 12px;display:flex;align-items:center;justify-content:space-between;gap:8px;border-bottom:1px solid rgba(255,224,121,.21);background:rgba(4,12,19,.35)}
.ktoHead span{color:var(--ktoAccent);font:900 9px/1 var(--fT);letter-spacing:.13em}.ktoHead b{padding:5px 7px;border:1px solid rgba(255,224,120,.48);border-radius:7px;color:var(--ktoAccent);font:900 9px/1 var(--fT);letter-spacing:.07em;background:rgba(0,0,0,.25)}
.ktoHero{position:relative;z-index:1;display:grid;grid-template-columns:82px 1fr;gap:10px;align-items:center}.ktoPortrait{position:relative;width:82px;height:82px;border-radius:11px;overflow:hidden;border:1px solid rgba(117,214,255,.62);background:#07131e;box-shadow:0 0 15px rgba(66,190,247,.16)}
.ktoPortrait>img{width:100%;height:100%;display:block;object-fit:cover}.ktoPortrait>span{position:absolute;right:4px;bottom:4px;width:34px;height:34px;display:flex;align-items:center;justify-content:center;border-radius:8px;background:rgba(3,12,20,.88);border:1px solid rgba(116,214,255,.48)}
.ktoPortrait .facIc{width:28px!important;height:28px!important;object-fit:contain}.ktoIdentity{min-width:0}.ktoIdentity small{display:block;color:#77d8ff;font:900 9px/1 var(--fT);letter-spacing:.14em}.ktoIdentity>b{display:block;margin:4px 0;color:#fff;font:900 14px/1.05 var(--fT);letter-spacing:.07em}.ktoIdentity i{display:block;color:#d8ecf8;font:800 9px/1.2 var(--fT);font-style:normal}.ktoIdentity p{margin:5px 0 0;color:#91adbf;font-size:9px;line-height:1.35;font-weight:650}
.ktoUgaPortrait{display:grid;place-items:center;background:radial-gradient(circle at 50% 42%,rgba(80,219,255,.2),transparent 44%),linear-gradient(145deg,#0a2638,#030b12);box-shadow:0 0 18px rgba(66,190,247,.2),inset 0 0 0 1px rgba(164,231,255,.1)}
.ktoUgaPortrait::before,.ktoUgaPortrait::after{content:'';position:absolute;border:1px solid rgba(110,224,255,.42);border-radius:50%;transform:rotate(-24deg)}
.ktoUgaPortrait::before{width:58px;height:58px}.ktoUgaPortrait::after{width:70px;height:28px;border-left-color:transparent;border-right-color:transparent}
.ktoPortrait>span.ktoUgaSeal{position:relative;right:auto;bottom:auto;z-index:1;width:auto;height:auto;display:grid;gap:4px;padding:0;border:0;border-radius:0;background:none;text-align:center}
.ktoUgaSeal b{color:#a9ecff;font:900 19px/1 var(--fT);letter-spacing:.16em;text-shadow:0 0 9px rgba(74,213,255,.7)}.ktoUgaSeal i{color:#ffe079;font:900 8px/1 var(--fT);font-style:normal;letter-spacing:.2em}
.ktoTeach{position:relative;z-index:1;display:flex;flex-wrap:wrap;gap:5px;margin-top:10px}.ktoTeach span{flex:1 1 29%;min-width:82px;padding:6px 5px;border-radius:7px;text-align:center;color:#a9c8da;background:rgba(3,12,20,.55);border:1px solid rgba(116,167,200,.2);font:850 9px/1 var(--fT);letter-spacing:.06em}
.ktoProgress{position:relative;z-index:1;margin-top:9px;padding:8px 9px;border-radius:9px;background:rgba(3,11,18,.58);border:1px solid rgba(119,177,212,.22)}.ktoProgress>div:first-child{display:flex;align-items:center;justify-content:space-between}.ktoProgress span{color:#8aa9bf;font:900 9px/1 var(--fT);letter-spacing:.11em}.ktoProgress b{color:var(--ktoAccent);font:900 10px/1 var(--fT)}
.ktoProgressTrack{height:5px;margin-top:6px;border-radius:5px;overflow:hidden;background:#07121d!important}.ktoProgressTrack i{display:block;height:100%;border-radius:inherit;background:linear-gradient(90deg,#2bb9ef,var(--ktoAccent));box-shadow:0 0 8px var(--ktoAccent)}.ktoProgress small{display:block;margin-top:5px;color:#809aad;font-size:9px;line-height:1.25;font-weight:700}
.ktoFacts{position:relative;z-index:1;display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-top:8px}.ktoFacts div{padding:6px 3px;border-radius:8px;text-align:center;background:rgba(5,15,23,.62);border:1px solid rgba(110,167,200,.2)}.ktoFacts b,.ktoFacts span{display:block}.ktoFacts b{color:#eaf8ff;font:900 9px/1 var(--fT)}.ktoFacts span{margin-top:3px;color:#7998ad;font:800 9px/1 var(--fT);letter-spacing:.06em}
.ktoAction{position:relative;z-index:1;width:100%;min-height:50px;margin-top:9px;padding:9px;border-radius:9px;border:1px solid rgba(255,232,144,.82);color:#171204;background:linear-gradient(180deg,#fff0a1,#d5a42e);box-shadow:0 0 14px rgba(255,207,69,.16);font:900 9px/1 var(--fT);letter-spacing:.09em}.keelTrainingOp.done .ktoAction{border-color:rgba(139,240,183,.7);background:linear-gradient(180deg,#b8f5d1,#58bf88)}
@media (max-width:380px){
#keelWrap{ top:calc(var(--sat) + 196px); width:92vw; }
#keelTxt{ font-size:12px; }
#keelTrainingCallout{width:94vw}.ktMiniIdentity>img{display:none}#keelTrainingCallout>button{flex-basis:92px;min-width:92px}
.keelTrainingOp{padding-left:10px;padding-right:10px}.ktoHead{margin-left:-10px;margin-right:-10px;padding-left:10px;padding-right:10px}.ktoHero{grid-template-columns:72px 1fr}.ktoPortrait{width:72px;height:76px}.ktoTeach span{min-width:76px}
}
@media (prefers-reduced-motion:reduce){
#keelWrap{ transition:none; }
#keelBar{ transition:none; }
#keelBar.pulse{ animation:none; }
#keelBar.pulse #keelBadge .kr1,#keelBar.pulse #keelBadge .kr2{ animation:none; }
#keelProgress i{transition:none}
.keelFocus,#keelMapCue{animation:none!important}
}
/* SKIP vs END. The same button leaves guidance (harmless) or abandons a
training match (destructive). Only the destructive state is dressed as
destructive — a bordered amber chip rather than a transparent 9px hint. */
#keelSkip.keelSkipEnd{
background:rgba(255,150,60,.14); border:1px solid rgba(255,170,80,.55);
color:#ffcf9a; letter-spacing:.10em;
}
#keelSkip.keelSkipEnd:active{ background:rgba(255,150,60,.30); color:#fff; }
/* ============================================================================
WAR TABLE PRIMER — src/warprimer.js
----------------------------------------------------------------------------
The card lives INSIDE the active .mfStagePanel rather than floating over it,
so there is deliberately no position/z-index/pointer-events here: it is a
block in the stage's own flow and inherits that panel's scrolling. It reuses
--panelG2 and the HUD type ramp for the same reason KEEL does, but takes the
war table's own amber-gold accent instead of KEEL's cyan — this is table
chrome, not the ship talking.
============================================================================ */
.wtpCard{
display:block; margin:0 0 12px; padding:11px 13px 10px;
background:var(--panelG2,linear-gradient(160deg,rgba(14,22,30,.94),rgba(8,13,19,.96)));
border:1px solid rgba(255,196,110,.34); border-radius:10px;
box-shadow:inset 0 1px 0 rgba(255,220,160,.14),0 6px 18px rgba(0,0,0,.42);
}
.wtpCard>header{
display:flex; align-items:baseline; justify-content:space-between; gap:10px;
margin-bottom:6px;
}
.wtpCard>header>span{
font:600 10px/1 var(--fU,system-ui); letter-spacing:.14em; color:#ffc86e;
}
.wtpCard>header>b{
font:700 10px/1 var(--fU,system-ui); letter-spacing:.1em; color:rgba(232,240,248,.78);
white-space:nowrap;
}
.wtpCard>p{
margin:0 0 9px; font:600 12.5px/1.35 var(--fU,system-ui); color:rgba(232,240,248,.90);
}
.wtpFoot{ display:flex; align-items:center; justify-content:space-between; gap:10px; }
/* The route echoes the stage stepper at the top of the screen so the card and
the nav agree on where the player is, without the card scrolling that nav
out of view being a problem. */
.wtpFoot>i{
display:flex; align-items:center; gap:4px; flex-wrap:wrap; font-style:normal;
font:600 9.5px/1.2 var(--fU,system-ui); letter-spacing:.08em; color:rgba(232,240,248,.62);
}
.wtpFoot>i>u{ text-decoration:none; color:rgba(232,240,248,.42); }
.wtpFoot>i>em{ font-style:normal; }
.wtpFoot>i>em.past{ color:rgba(255,200,110,.78); }
.wtpFoot>i>em.on{ color:#ffc86e; }
.wtpDone{
flex:0 0 auto; min-height:44px; min-width:44px; padding:0 14px;
background:rgba(255,196,110,.13); border:1px solid rgba(255,196,110,.44);
border-radius:7px; color:#ffd79a;
font:700 11px/1 var(--fU,system-ui); letter-spacing:.12em;
}
.wtpDone:active{ background:rgba(255,196,110,.30); color:#fff; }
.wtpSkip{
flex:0 0 auto; min-height:44px; padding:0 10px;
background:transparent; border:0; color:rgba(232,240,248,.78);
font:700 10px/1 var(--fU,system-ui); letter-spacing:.12em;
}
.wtpSkip:active{ color:#fff; }
.wtpCard.wtpLast{ border-color:rgba(150,255,190,.36); }
.wtpCard.wtpLast>header>span,.wtpCard.wtpLast .wtpFoot>i>em.on{ color:#9fffc4; }
.wtpCard.wtpLast .wtpDone{
background:rgba(120,255,180,.13); border-color:rgba(150,255,190,.46); color:#bfffd9;
}
@media (max-width:430px){
.wtpCard{ padding:9px 10px 9px; }
.wtpFoot{ display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px; }
.wtpDone,.wtpSkip{ min-width:0;width:100%;padding:0 6px; }
.wtpDone:only-child{ grid-column:1/-1; }
}
|