  :root{
    --steel:#23282e; --steel2:#171b20; --panel:#1b1f24; --panel2:#0f1216;
    --edge:#05070a; --hi:#363c44; --ink:#c9d1d9; --bright:#e6edf3; --muted:#7d8590;
    --sol:#14f195; --soru:#9945ff; --soru-lt:#b98cff; --sci:#5ab0e8;
    --gold:#14f195; /* legacy alias → Solana teal accent */
  }
  *{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
  html,body{margin:0;height:100%;overflow:hidden;background:#a7b7ba;font-family:"Trebuchet MS","Segoe UI",system-ui,sans-serif;color:var(--ink);user-select:none}
  /* body is the fixed, TRANSFORM-FREE viewport clip. The rotate-lock wrappers below are
     position:ABSOLUTE inside it (not fixed): iOS Safari composites a transform on a fixed
     element unreliably (it defers the paint until the first gesture — the splash stayed upright
     and the canvas measured against the stale portrait box), but composites the same transform
     on an absolutely-positioned element eagerly. Overlays appended to body (#_err, #perfHud) are
     position:fixed and stay viewport-anchored because body carries no transform. */
  body{position:fixed;inset:0;width:100%;height:100%}
  /* NOTE (iOS): every gameplay UI element inside #gameRoot is position:ABSOLUTE, not fixed.
     The forceLandscape rotation transforms #gameRoot; per spec a transformed ancestor becomes the
     containing block for fixed descendants, but iOS Safari applies that inconsistently — fixed
     children escaped the rotation / sized against the real viewport, which is why the game came up
     unrotated and garbled ("not loading") on iPhones. Absolute children anchor to #gameRoot
     identically in every engine, rotated or not. */
  #cv{display:block;position:absolute;top:0;left:0;width:100%;height:100%;touch-action:none;cursor:crosshair}
  /* ---- scrollbars (dark) ---- */
  #builds::-webkit-scrollbar,#advisor::-webkit-scrollbar{height:6px;width:6px}
  #builds::-webkit-scrollbar-thumb,#advisor::-webkit-scrollbar-thumb{background:#2c333b;border-radius:3px}
  #builds::-webkit-scrollbar-track,#advisor::-webkit-scrollbar-track{background:transparent}
  /* ---- top resource bar ---- */
  #top{position:absolute;top:0;left:0;right:0;height:42px;display:flex;align-items:center;gap:4px;padding:0 8px;
    background:linear-gradient(#1b1f24,#101317);border-bottom:1px solid #000;box-shadow:0 2px 8px rgba(0,0,0,.6);z-index:10;overflow-x:auto}
  .res{display:flex;align-items:center;gap:5px;padding:3px 9px 3px 6px;background:linear-gradient(#262b31,#1a1e23);
    border:1px solid var(--edge);border-radius:4px;box-shadow:inset 0 1px 0 var(--hi);font-weight:700;font-size:12px;color:var(--ink);white-space:nowrap}
  .res .ic{width:15px;height:15px}
  .res.neg b{color:#ff5a4d}
  #age{margin-left:auto;display:flex;align-items:center;gap:7px;color:var(--bright);font-family:"Yu Mincho",serif;font-size:13px;text-shadow:0 1px 2px #000;white-space:nowrap}
  #advanceBtn{font:inherit;font-weight:700;cursor:pointer;color:var(--sol);font-size:11px;padding:5px 10px;border-radius:4px;
    background:linear-gradient(#262b31,#161a1f);border:1px solid var(--edge);box-shadow:inset 0 1px 0 var(--hi)}
  #advanceBtn:disabled{filter:grayscale(.5) brightness(.8);cursor:not-allowed;opacity:.6;color:var(--muted)}
  #advanceBtn.ready{animation:pulse 1.4s infinite;color:var(--sol)}
  @keyframes pulse{50%{box-shadow:inset 0 1px 0 var(--hi),0 0 11px rgba(20,241,149,.55)}}
  /* ---- collective Kami meter (compact, lives in the top bar by the astrology; shared by all) ---- */
  .kamiMeter{gap:5px}
  .kmBar{position:relative;width:62px;height:7px;background:#0c0f12;border:1px solid var(--edge);border-radius:4px;overflow:hidden}
  .kmFill{position:absolute;top:0;bottom:0;left:0;width:0%;
    background:linear-gradient(90deg,rgba(20,241,149,.45),rgba(20,241,149,.9));
    box-shadow:0 0 6px rgba(20,241,149,.5);transition:width .7s cubic-bezier(.25,.8,.3,1)}
  .kmPct{font-size:10px;color:var(--bright);min-width:24px;text-align:right}
  .kamiMeter.near .kmFill{animation:kamiPulse 1.2s ease-in-out infinite}
  @keyframes kamiPulse{50%{box-shadow:0 0 14px rgba(20,241,149,.9)}}
  .kamiMeter.maxed .kmFill{width:100%;
    background:linear-gradient(90deg,rgba(20,241,149,.65),rgba(153,69,255,.7),rgba(20,241,149,.65));
    background-size:200% 100%;animation:kamiAurora 6s linear infinite}
  @keyframes kamiAurora{0%{background-position:0 0}100%{background-position:200% 0}}
  /* ---- bottom panel ---- */
  #panel{position:absolute;left:0;right:0;bottom:0;z-index:10;background:linear-gradient(#1b1f24,#0e1115);
    border-top:1px solid #000;box-shadow:0 -2px 10px rgba(0,0,0,.6);padding:6px 9px 7px;display:flex;gap:9px;align-items:center}
  #builds{display:flex;flex-wrap:nowrap;gap:5px;flex:1;overflow-x:auto;overflow-y:hidden;padding-bottom:2px}
  .bbtn{position:relative;width:66px;height:68px;cursor:pointer;border-radius:5px;background:linear-gradient(#23282e,#161a1f);
    border:1px solid var(--edge);box-shadow:inset 0 1px 0 var(--hi);overflow:hidden}
  .bbtn:hover{filter:brightness(1.18)} .bbtn.sel{border-color:var(--sol);box-shadow:inset 0 0 0 1px var(--sol),0 0 8px rgba(20,241,149,.5)}
  .bbtn canvas{position:absolute;top:1px;left:50%;transform:translateX(-50%)}
  .bbtn .nm{position:absolute;left:0;right:0;bottom:0;height:14px;line-height:14px;text-align:center;
    background:rgba(0,0,0,.78);color:var(--ink);font-size:9px;font-weight:700;letter-spacing:.2px;z-index:2;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:0 2px}
  .bbtn .cost{position:absolute;left:2px;top:1px;font-size:8px;line-height:10px;color:var(--sol);z-index:3;font-weight:700;
    background:rgba(0,0,0,.7);border-radius:2px;padding:0 3px}
  .bbtn.lock{opacity:.4;filter:grayscale(.7);cursor:not-allowed}
  .bbtn .lk{position:absolute;top:1px;right:3px;font-size:11px;z-index:3}
  /* ---- sidebar ---- */
  #sidebar{position:absolute;top:50px;right:9px;width:178px;z-index:9;display:flex;flex-direction:column;gap:5px;
    color:var(--ink);font-size:11px;padding:7px;border-radius:8px;
    background:linear-gradient(rgba(23,27,32,.82),rgba(12,14,18,.82));border:1px solid var(--edge);
    box-shadow:0 6px 20px rgba(0,0,0,.5),inset 0 1px 0 rgba(255,255,255,.05);
    backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
  #sidebar{cursor:grab}
  #sidebar.dragging{cursor:grabbing;transition:none;box-shadow:0 10px 28px rgba(0,0,0,.6),0 0 0 1px var(--sol)}
  .sbGrip{cursor:grab;touch-action:none;user-select:none;-webkit-user-select:none;text-align:center;
    font-size:10px;letter-spacing:2px;font-weight:700;color:#6a7480;padding:1px 0 4px;line-height:1;
    border-bottom:1px solid var(--edge);margin-bottom:2px}
  .sbGrip span{color:#4a525c} .sbGrip:hover{color:var(--ink)} .sbGrip:active{cursor:grabbing}
  .scard{background:rgba(8,10,13,.55);border:1px solid var(--edge);border-radius:5px;padding:5px 7px}
  #advisor{min-height:34px;max-height:62px;overflow-y:auto;line-height:1.3;color:var(--ink)} #advisor b{color:var(--sol)}
  .demand{display:flex;gap:5px;margin-top:2px}
  .dem{flex:1;text-align:center} .dem .bar{height:5px;background:#0c0f12;border-radius:3px;overflow:hidden;margin-top:1px}
  .dem .fill{height:100%;width:0} .dem.R .fill{background:#2ea043}.dem.C .fill{background:#388bfd}.dem.I .fill{background:#d29922}
  .w3{display:flex;justify-content:space-between;font-weight:700} .w3 .sol{color:var(--sol)} .w3 .soru{color:var(--soru-lt)}
  .netRow{display:flex;justify-content:space-between;align-items:center;font-weight:700;font-size:10px}
  .netRow .lbl{display:flex;align-items:center;gap:4px;color:var(--muted);font-weight:600}
  .netRow .ic{width:13px;height:13px} .netRow b{color:var(--sol)} .netRow.neg b{color:#ff5a4d}
  /* ---- three grouped sidebar sections: economy / build / raid ---- */
  .ssec{display:flex;flex-direction:column;gap:5px;padding:6px 6px 7px;border-radius:6px;
    border:1px solid var(--edge);background:rgba(8,10,13,.42)}
  .ssec.eco{border-color:rgba(20,241,149,.20)}
  .ssec.bld{border-color:rgba(108,148,196,.20)}
  .ssec.raid{border-color:rgba(255,90,77,.30);background:rgba(28,15,16,.4)}
  .shdr{display:flex;align-items:center;gap:6px;font-size:8px;font-weight:800;letter-spacing:1.2px;
    text-transform:uppercase;opacity:.85;color:var(--muted);margin:0 1px 1px}
  .shdr::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,currentColor,transparent);opacity:.35}
  .shdr .jp{font-family:"Yu Mincho",serif;font-size:11px;letter-spacing:0;opacity:.95}
  .shdr.eco{color:var(--sol)} .shdr.bld{color:var(--soru-lt)} .shdr.raid{color:#ff7a6a}
  /* ---- tool / action buttons ---- */
  .pbtns{display:flex;gap:5px;flex-wrap:wrap}
  .pbtn{flex:1;min-width:54px;font:inherit;font-weight:700;font-size:10px;cursor:pointer;color:var(--ink);padding:5px 0;border-radius:4px;text-align:center;
    background:linear-gradient(#262b31,#171b20);border:1px solid var(--edge);box-shadow:inset 0 1px 0 var(--hi)}
  .pbtn:active{transform:translateY(1px)} .pbtn.on{border-color:var(--sol);box-shadow:inset 0 0 0 1px var(--sol)}
  .pbtn.pvp{color:#ff7a6a} .pbtn.pvp.on{border-color:#ff5a4d;box-shadow:inset 0 0 0 1px #ff5a4d;background:linear-gradient(#2a1416,#1c0f10)}
  /* icon-only action buttons (MOVE/QUERY/RAZE/DOUSE/PILLAGE/ARSON/GUARD/DEEDS) */
  .pbtns.ircon{gap:4px}
  .pbtn.ico{padding:6px 0;min-width:0;display:flex;align-items:center;justify-content:center}
  .pbtn.ico svg{width:18px;height:18px;display:block;pointer-events:none}
  /* DEX / VALUE accent buttons */
  #dexBtn{color:var(--sol)} #valBtn{color:var(--soru-lt)} #deedBtn{color:var(--sol)} #guardBtn{color:var(--sci)}
  /* ---- zoom cluster ---- */
  #zoom{position:absolute;right:9px;bottom:96px;display:flex;flex-direction:column;gap:5px;z-index:9}
  .zb{width:36px;height:36px;font:inherit;font-weight:700;font-size:17px;cursor:pointer;color:var(--ink);border-radius:5px;
    background:linear-gradient(#262b31,#171b20);border:1px solid var(--edge);box-shadow:inset 0 1px 0 var(--hi)} .zb:active{transform:translateY(1px)}
  /* ---- top-right links + options ---- */
  #topLinks{display:flex;align-items:center;gap:5px;margin-left:8px}
  .tlBtn{font:inherit;font-weight:700;cursor:pointer;color:var(--ink);font-size:11px;padding:5px 9px;border-radius:4px;text-decoration:none;
    background:linear-gradient(#262b31,#161a1f);border:1px solid var(--edge);box-shadow:inset 0 1px 0 var(--hi);white-space:nowrap;display:inline-flex;align-items:center;gap:4px}
  .tlBtn:hover{filter:brightness(1.18)} .tlBtn:active{transform:translateY(1px)}
  .tlBtn svg{width:13px;height:13px;flex:0 0 auto}
  #optModal{position:absolute;inset:0;z-index:30;background:rgba(0,0,0,.72);display:none;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
  #optModal.show{display:flex}
  #optBox{width:320px;background:linear-gradient(#1b1f24,#0f1216);border:1px solid var(--sol);border-radius:10px;padding:16px;color:var(--ink);box-shadow:0 0 24px rgba(20,241,149,.18),0 10px 40px rgba(0,0,0,.6)}
  #optBox h3{margin:0 0 12px;color:var(--sol);font-family:"Yu Mincho",serif}
  .optRow{display:flex;flex-direction:column;gap:5px;margin:12px 0}
  .optRow .optLbl{display:flex;justify-content:space-between;font-size:12px}
  .optRow .optLbl b{color:var(--ink);font-weight:700}
  .optRow .optVal{color:var(--sol);font-weight:700}
  .optRow input[type="range"]{width:100%;accent-color:var(--sol);cursor:pointer}
  .optChk{display:flex;align-items:center;justify-content:space-between;gap:8px;margin:14px 0;font-size:12px;cursor:pointer}
  .optChk input{width:18px;height:18px;accent-color:var(--sol);cursor:pointer}
  #optClose{font:inherit;font-weight:700;cursor:pointer;padding:7px 10px;border-radius:5px;border:1px solid var(--edge);color:var(--ink);
    width:100%;margin-top:6px;background:linear-gradient(#262b31,#171b20);box-shadow:inset 0 1px 0 var(--hi)} #optClose:active{transform:translateY(1px)}
  /* ---- toasts ---- */
  #toast{position:absolute;left:50%;top:50px;transform:translateX(-50%);z-index:20;display:flex;flex-direction:column;gap:4px;align-items:center;pointer-events:none}
  .tmsg{background:rgba(8,10,13,.92);color:var(--bright);border:1px solid var(--sol);border-radius:5px;padding:4px 11px;font-size:11px;box-shadow:0 3px 12px rgba(0,0,0,.6);opacity:0;animation:tin .3s forwards}
  .tmsg b{color:var(--sol)} @keyframes tin{to{opacity:1}}
  /* ---- title ---- */
  #title{position:absolute;top:46px;left:10px;z-index:9;font-family:"Yu Mincho",serif;color:var(--bright);text-shadow:0 2px 5px #000;font-size:17px;letter-spacing:1px;pointer-events:none}
  #title b{color:var(--sol)} #title span{font-size:10px;opacity:.65;color:var(--soru-lt)}
  /* ---- DEX modal ---- */
  #dexModal{position:absolute;inset:0;z-index:30;background:rgba(0,0,0,.72);display:none;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
  #dexModal.show{display:flex}
  #dexBox{width:300px;background:linear-gradient(#1b1f24,#0f1216);border:1px solid var(--sol);border-radius:10px;padding:16px;color:var(--ink);box-shadow:0 0 24px rgba(20,241,149,.18),0 10px 40px rgba(0,0,0,.6)}
  #dexBox h3{margin:0 0 8px;color:var(--sol);font-family:"Yu Mincho",serif} #dexBox .row{display:flex;justify-content:space-between;margin:5px 0}
  #dexBox .sol{color:var(--sol)} #dexBox .soru{color:var(--soru-lt)}
  #dexBox input{width:90px;background:#0c0f12;border:1px solid var(--edge);border-radius:4px;color:var(--bright);padding:4px 6px;font:inherit}
  #dexBox button{font:inherit;font-weight:700;cursor:pointer;padding:6px 10px;border-radius:5px;border:1px solid var(--edge);color:var(--ink);
    background:linear-gradient(#262b31,#171b20);box-shadow:inset 0 1px 0 var(--hi)} #dexBox button:active{transform:translateY(1px)}
  #dxBuy{color:var(--sol)} #dxSell{color:var(--soru-lt)}
  /* ---- responsive ---- */
  @media(max-width:760px){
    #title{display:none}
    #top{height:38px;gap:3px;padding:0 5px}
    .res{padding:2px 6px 2px 5px;font-size:10px;border-radius:4px} .res .ic{width:12px;height:12px}
    #age{font-size:11px;gap:5px} #age button{font-size:11px;padding:2px 6px}
    #topLinks{gap:3px;margin-left:4px} .tlBtn{font-size:9px;padding:3px 6px} .tlBtn svg{width:11px;height:11px}
    #panel{padding:5px 6px 6px;gap:6px;max-height:42vh}
    #builds{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;height:60px;max-height:60px;-webkit-overflow-scrolling:touch}
    .bbtn{width:52px;height:54px;flex:0 0 auto} .bbtn .nm{height:12px;line-height:12px;font-size:8px} .bbtn .cost{font-size:7px}
    #sidebar{top:44px;right:6px;width:150px;max-height:62vh;overflow-y:auto;font-size:10px;gap:3px;padding:6px}
    #advisor{min-height:0;max-height:48px;overflow-y:auto;font-size:10px;line-height:1.25}
    .pbtn{min-width:40px;font-size:9px;padding:4px 0}
    #zoom{left:6px;right:auto;bottom:auto;top:44px}
    .zb{width:38px;height:38px;font-size:18px}
  }
  @media(max-width:760px) and (orientation:landscape){
    #panel{max-height:54vh} #builds{height:54px;max-height:54px} #sidebar{width:120px}
  }
  /* ---- auto-landscape on portrait phones ----
     #gameRoot wraps all gameplay UI (canvas, hud, panel, modals); #boot is the
     pre-game splash. On a small portrait screen we don't ask the player to
     physically rotate their phone — we rotate both elements together with a CSS
     transform so the whole experience, splash included, is immediately playable
     in landscape. The unrotated box is pre-sized to swapped *dynamic* viewport
     dimensions (100dvh x 100dvw, not 100vh x 100vw — static vh/vw overshoot on
     mobile browsers whenever the address bar is showing, which is what produced
     the squished/clipped layout); rotating it 90° makes its on-screen bounding box
     exactly fill the real visible portrait viewport, so every downstream
     getBoundingClientRect()-based layout call (resize(), fit()) just works without
     any coordinate-remapping changes. */
  /* Base state fills the viewport so the ABSOLUTE UI children (see #cv note) anchor to it in both
     orientations. overflow:hidden guards against sub-pixel bleed at the rotated box's edges. */
  #gameRoot{position:absolute;inset:0;overflow:hidden}
  #gameRoot.forceLandscape{
    position:absolute; inset:auto; top:50%; left:50%;
    /* static vh/vw first as a fallback for iOS < 15.4 (no dvh/dvw support — the un-parsed
       declarations were dropped there, leaving the rotated box with no dimensions at all).
       NOTE: these are only a fallback — __updateRotateLock sets width/height inline in *px*
       so the rotated box never depends on iOS's flaky dvh/dvw first-paint evaluation. */
    width:100vh; height:100vw;
    width:100dvh; height:100dvw;
    /* translateZ(0) forces a GPU layer that iOS paints EAGERLY. Do NOT use will-change:transform
       here: on a fixed/absolute box it promotes a *lazily*-painted layer, which is what made iOS
       defer the rotation until the first gesture. backface-visibility is a harmless extra hint. */
    transform:translate(-50%,-50%) rotate(90deg) translateZ(0);
    transform-origin:center center;
    -webkit-backface-visibility:hidden; backface-visibility:hidden;
  }
  /* ---- boot splash ---- */
  /* z-index 100. #boot sits above #gameRoot. On small portrait screens it rotates
     in lockstep with #gameRoot (via the shared .forceLandscape toggle) so the splash
     reads correctly in the same landscape orientation as the rest of the game,
     instead of staying upright while everything underneath is sideways. */
  #boot{position:absolute;inset:0;z-index:100;background:#000;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;cursor:pointer;
    /* iOS: without these the splash tap is consumed as a text-selection / gesture on the rotated
       (forceLandscape) layer and pointerdown/click never fire. Mirror #cv's touch-action. */
    touch-action:manipulation;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;
    transition:opacity .6s ease; -webkit-tap-highlight-color:transparent}
  #boot.forceLandscape{
    position:absolute; inset:auto; top:50%; left:50%;
    width:100vh; height:100vw;       /* iOS <15.4 fallback — see #gameRoot.forceLandscape */
    width:100dvh; height:100dvw;     /* both only fallbacks — JS sets px width/height inline */
    transform:translate(-50%,-50%) rotate(90deg) translateZ(0);
    transform-origin:center center;
    -webkit-backface-visibility:hidden; backface-visibility:hidden;
    /* iOS Safari defers COMPOSITING a transformed element until the first user gesture. For the
       splash that first gesture is the tap that dismisses it — so the rotation was never painted
       and the player only ever saw the upright ("vertical") tap-to-enter screen. An element with an
       animating TRANSFORM is promoted to a composited layer and repainted every frame, which forces
       the rotation to composite immediately with no gesture. We animate the transform between two
       visually identical states (translateZ 0 ↔ 0.001px) so the 90° rotation itself is untouched
       (the canvas pointer remap in evp() stays valid) but the layer is kept live. Animating the
       transform is a much stronger iOS composite trigger than animating opacity was. Runs only on
       portrait phones (where .forceLandscape applies) and stops the instant the splash dismisses. */
    animation:bootComposite 1.2s linear infinite;
  }
  /* Once dismissing, drop the keep-alive animation so the opacity fade-out (transition) is clean. */
  #boot.forceLandscape.hide{animation:none}
  @keyframes bootComposite{
    0%,100%{transform:translate(-50%,-50%) rotate(90deg) translateZ(0)}
    50%    {transform:translate(-50%,-50%) rotate(90deg) translateZ(0.001px)}
  }
  #boot.hide{opacity:0;pointer-events:none}
  #bootLogo{width:148px;height:auto;display:block;filter:drop-shadow(0 4px 18px rgba(20,241,149,.18))}
  #bootTitle{font-family:"Trebuchet MS","Segoe UI",system-ui,sans-serif;font-weight:700;letter-spacing:3px;font-size:34px;color:var(--bright);
    text-align:center;padding:0 20px}
  #bootKanji{font-family:"Yu Mincho",serif;font-size:22px;letter-spacing:6px;color:var(--sol);text-shadow:0 0 14px rgba(20,241,149,.45)}
  #bootTap{margin-top:26px;font-size:11px;letter-spacing:2px;color:var(--muted);opacity:.75;animation:bootPulse 1.8s infinite}
  @keyframes bootPulse{0%,100%{opacity:.35}50%{opacity:.85}}
  @media(max-width:760px){
    #bootLogo{width:104px}
    #bootTitle{font-size:24px;letter-spacing:2px} #bootKanji{font-size:16px;letter-spacing:4px}
  }
