/* =====================================================================
   BALEN DESIGN SYSTEM v1 - Home (Owner Command Center)
   ---------------------------------------------------------------------
   Presentation ONLY, scoped html.skin-balen (shared by Midnight + Air).
   ONE interface; only MATERIALS change between the two appearances:
     - Midnight (html.skin-midnight): deep graphite, glass, white type
     - Air      (html.skin-air):      architectural white, soft gray, blue nav
   Same layout / hierarchy / spacing / typography / motion for both.
   Chrome uses --bh-* material tokens (per-theme below); content over the
   hero photograph uses fixed light-on-photo tokens (photo legibility).
   Data injected by js/billy-home.js from Classic's own in-memory state.
   ===================================================================== */

/* ---- material tokens : shared + on-photo (fixed) ------------------- */
html.skin-balen {
  --bh-on-photo:   #F5F5F2;
  --bh-on-photo-2: rgba(245,245,242,0.72);
  --bh-on-photo-3: rgba(245,245,242,0.5);
  --bh-photo-veil: rgba(8,9,10,0.55);            /* readiness / instrument band over photo */
  --bh-ignition:   #E23B32;                       /* Rosso red - action, both themes */
}
/* ---- MIDNIGHT (dark) ---------------------------------------------- */
html.skin-midnight {
  --bh-bg:          #08090A;
  --bh-surface:     #0D0F11;
  --bh-text:        #F3F2EE;
  --bh-text-2:      #96979B;
  --bh-text-3:      #5A5C60;
  --bh-glass:       rgba(255,255,255,0.05);
  --bh-glass-edge:  rgba(255,255,255,0.08);
  --bh-hairline:    rgba(255,255,255,0.06);
  --bh-hover-edge:  rgba(255,255,255,0.13);
  --bh-panel-shadow: inset 0 0 0 1px rgba(255,255,255,0.07), 0 16px 48px rgba(0,0,0,0.40);
  --bh-nav-bg:      rgba(13,15,17,0.72);
  --bh-menu-bg:     #14171A;
  --bh-accent:      #17BFAB;                       /* teal */
  --bh-ready:       #33D68F;
  --bh-attn:        #FFA24B;
  --bh-action:      #FF4B42;
  --bh-info:        #57A6FF;
  --bh-hero-placeholder: #0D0F11;   /* hero fallback; already dark, value unchanged */
  --bh-caption:     rgba(245,245,242,0.5);  /* == --bh-on-photo-3; Midnight unchanged */
  /* Status ink used ON A SURFACE rather than over the photograph. On
     Midnight the surface is dark, so these are identical to the on-photo
     values above and nothing changes. They exist because Air needs the two
     to differ -- see the Air block. */
  --bh-ready-s:     #33D68F;
  --bh-attn-s:      #FFA24B;
  --bh-action-s:    #FF4B42;
  --bh-hero-veil:   0;                             /* no extra veil over photo */
}
/* ---- AIR (light) -------------------------------------------------- */
html.skin-air {
  --bh-bg:          #EEF1F5;
  --bh-surface:     #FFFFFF;
  --bh-text:        #131A22;
  --bh-text-2:      #5A6472;
  /* #97A2AF is 2.5:1 on white -- it reads as a tint, not as text, and Home
     uses this tier for real content (metric labels, partner roles, balance
     roles, nav labels). Darkened to the same tertiary the rest of the app
     uses under Air, so Home and every other surface agree. Every consumer of
     this token sits on a SURFACE, never over the photograph. */
  --bh-text-3:      #636D7A;
  --bh-glass:       #FFFFFF;
  --bh-glass-edge:  rgba(17,26,40,0.08);
  --bh-hairline:    rgba(17,26,40,0.07);
  --bh-hover-edge:  rgba(17,26,40,0.14);
  --bh-panel-shadow: 0 1px 0 rgba(17,26,40,0.03), 0 14px 34px rgba(30,45,70,0.09);
  --bh-nav-bg:      rgba(255,255,255,0.86);
  --bh-menu-bg:     #FFFFFF;
  --bh-accent:      #2F6BFF;                       /* blue navigation */
  --bh-hero-placeholder: #141B24;   /* dark, so on-photo ink survives a load/403 */
  --bh-caption:     #636D7A;        /* captions on a SURFACE, not over the photo */
  /* These three stay BRIGHT: their only remaining consumers are the
     readiness panel and its icons, which sit over the photograph on the
     dark --bh-photo-veil. Darkening them there would bury them. */
  --bh-ready:       #0E9E63;
  --bh-attn:        #C8791E;
  --bh-action:      #E5484D;
  /* ...and these are the same three colours for use ON A SURFACE, where the
     ground is white or #EEF1F5. The bright values measure 3.0:1, 3.3:1 and
     3.9:1 there -- below AA for the KPI figures, balances and money amounts
     that carry them. Darkened to 5.34 / 5.92 / 5.30, matching the money
     direction tokens the rest of the app uses under Air. */
  --bh-ready-s:     #0E7A55;
  --bh-attn-s:      #8A5A0F;
  --bh-action-s:    #C4373C;
  --bh-info:        #2F6BFF;
  --bh-ignition:    #E5484D;
}

/* ---- shell -------------------------------------------------------- */
html.skin-balen #app.bh-active { background: var(--bh-bg); max-width: none; margin: 0; padding: 0; min-height: 100vh; }
html.skin-balen .bh-root {
  background: var(--bh-bg); color: var(--bh-text); font-family: var(--font-sans);
  min-height: 100vh; -webkit-font-smoothing: antialiased; position: relative; overflow-x: hidden;
  padding-bottom: 104px;
}
html.skin-balen .bh-root *, html.skin-balen .bh-root *::before, html.skin-balen .bh-root *::after { box-sizing: border-box; }
html.skin-balen .bh-root p { margin: 0; }
html.skin-balen .bh-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
html.skin-balen .bh-tap { cursor: pointer; }

html.skin-balen .bh-navbtn svg, html.skin-balen .bh-ignition svg,
html.skin-balen .bh-row-chev svg, html.skin-balen .bh-cta svg, html.skin-balen .bh-ready-head svg,
html.skin-balen .bh-ready-item svg {
  stroke: currentColor; fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
html.skin-balen .bh-ignition svg { stroke-width: 2; }

/* ---- header (Everything ready) ------------------------------------ */
html.skin-balen .bh-header { display: flex; justify-content: space-between; align-items: flex-start; padding: 22px 20px 0; }
html.skin-balen .bh-greeting { font-family: var(--font-serif); font-size: 20px; line-height: 26px; font-weight: 500; color: var(--bh-text-2); }
html.skin-balen .bh-status { font-size: 34px; line-height: 40px; font-weight: 700; letter-spacing: -0.5px; color: var(--bh-text); margin-top: 6px; }
html.skin-balen .bh-status-pill { display: inline-flex; align-items: center; gap: 7px; margin-top: 12px; border-radius: 999px; padding: 5px 12px; font-size: 12px; color: var(--bh-ready-s); background: color-mix(in srgb, var(--bh-ready-s) 12%, transparent); }
html.skin-balen .bh-status-pill.is-attn { color: var(--bh-attn-s); background: color-mix(in srgb, var(--bh-attn-s) 12%, transparent); }
html.skin-balen .bh-status-pill .bh-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
html.skin-balen .bh-avatar { width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0; margin-top: 4px; background: var(--bh-glass); box-shadow: inset 0 0 0 1px var(--bh-glass-edge); color: var(--bh-text-2); display: flex; align-items: center; justify-content: center; font-size: 11px; letter-spacing: 0.5px; border: none; cursor: pointer; }

/* ---- Balen Brief (a voice, not a card) ---------------------------- */
html.skin-balen .bh-copilot { font-family: var(--font-serif); font-size: 16px; line-height: 24px; color: var(--bh-text-2); padding: 14px 20px 0; }
html.skin-balen .bh-copilot .bh-verdict { color: var(--bh-text); }

/* ---- hero (asset photography) ------------------------------------- */
/* The hero's own background is what shows while the photo loads, and again if
   the signed URL 403s or expires. Everything painted on top of it -- the
   registration, the model, the readiness panel, the instrument band -- uses
   the FIXED light-on-photo ink (--bh-on-photo, #F5F5F2). So this surface must
   be dark in BOTH appearances. Using --bh-surface made it #FFFFFF under Air,
   which meant that during every cold load, and permanently on a photo error,
   the aircraft registration and all six instruments were white on white:
   present, focusable, screen-reader readable, and invisible. Midnight is
   unaffected (its --bh-surface was already #0D0F11) and keeps the same value. */
html.skin-balen .bh-hero { position: relative; margin-top: 20px; height: 320px; overflow: hidden; background: var(--bh-hero-placeholder, var(--bh-surface)); }
/* .bh-hero-media is the CROP FRAME's inner layer: inset:0 inside the
   overflow:hidden .bh-hero, painted background-size:cover, so at scale 1 it
   covers the frame exactly at every aspect ratio. --bh-hero-zoom (>= 1, set
   inline by js/billy-home.js from balenAssetHero.heroCssVars) scales it about
   --bh-focal, which is the SAME percentage pair as background-position; a
   uniform scale >= 1 about an interior origin only pushes the edges outward,
   so coverage is preserved and the image is never stretched. Both vars
   default to the pre-existing behaviour (scale 1 / centre) so the stock
   per-atype heroes are byte-for-byte unchanged. */
html.skin-balen .bh-hero-media { position: absolute; inset: 0; background-size: cover; background-position: center; background-repeat: no-repeat; filter: saturate(0.9) brightness(0.9) contrast(1.03); transform: scale(var(--bh-hero-zoom, 1)); transform-origin: var(--bh-focal, center); }
html.skin-balen .bh-hero[data-atype="aircraft"] .bh-hero-media { background-image: url(/assets/brand/billy/v1/hero-aircraft.jpg), radial-gradient(130% 100% at 72% 12%, #1b2a37 0%, #0a1017 100%); }
html.skin-balen .bh-hero[data-atype="boat"]     .bh-hero-media { background-image: url(/assets/brand/billy/v1/hero-boat.jpg),     radial-gradient(130% 100% at 72% 12%, #13232f 0%, #08121b 100%); }
html.skin-balen .bh-hero[data-atype="home"]     .bh-hero-media { background-image: url(/assets/brand/billy/v1/hero-home.jpg),     radial-gradient(130% 100% at 72% 12%, #2a2114 0%, #0e0a06 100%); background-position: center 42%; }
html.skin-balen .bh-hero[data-atype="vehicle"]  .bh-hero-media { background-image: url(/assets/brand/billy/v1/hero-vehicle.jpg),  radial-gradient(130% 100% at 72% 12%, #1f2226 0%, #0b0e10 100%); background-position: center 46%; }
html.skin-balen .bh-hero-scrim { position: absolute; inset: 0; background:
  linear-gradient(90deg, rgba(8,9,10,0.70) 0%, rgba(8,9,10,0.20) 34%, rgba(8,9,10,0) 62%),
  linear-gradient(180deg, rgba(8,9,10,0.44) 0%, rgba(8,9,10,0) 24%, rgba(8,9,10,0.32) 56%, rgba(8,9,10,0.96) 100%); }
/* Owner-uploaded asset photo. The signed URL is injected by js/billy-home.js
   as an INLINE background-image on .bh-hero-media (photo first, the same
   per-atype radial gradient second), which overrides the [data-atype] stock
   image above; until it resolves -- and again if it 403s or expires -- the
   stock/gradient stack below is what shows, so there is never a blank box or
   a broken-image state. Hero height is untouched (320px) -> no layout shift.
   An arbitrary user photo can be far brighter than the art-directed stock
   images, so with a photo present we STRENGTHEN the existing scrim rather
   than restyling the name/model/readiness/instrument type.
   The stock photograph is also CLEARED here: this asset HAS its own photo, so
   while the signed URL is being minted -- and permanently if it can never be
   minted (403/expired/offline) -- the honest fallback is the branded gradient,
   NOT a stand-in photograph of a different aircraft/boat/house sitting under
   the owner's asset name (and over-darkened by the stronger scrim). Same
   per-atype gradient the JS appends as layer 2, so the inline paint is a
   seamless upgrade of this. */
/* Owner crop: --bh-focal is "X% Y%" straight out of heroCssVars(), which is
   focal-point semantics (the image's X%/Y% point is pinned to the frame's
   X%/Y% point). It must WIN over the [data-atype] stock positions above
   (equal specificity, later in the file) so a "home" photo is not silently
   re-anchored to the stock `center 42%`.
   --bh-hero-filter is now written on EVERY photo hero by js/billy-home.js and
   carries heroCssVars().filterComposed verbatim. Since the 2026-07-26
   localized-overlay rework NS.HERO_BASE_FILTER is 'none': the owner's photo is
   NEVER dimmed or desaturated by default (only an explicit dark/contrast
   preset adds a filter). The fallback literal below is kept byte-identical to
   NS.HERO_BASE_FILTER so the two can never disagree. */
html.skin-balen .bh-hero.bh-has-photo .bh-hero-media { background-position: var(--bh-focal, center); filter: var(--bh-hero-filter, none); }
html.skin-balen .bh-hero.bh-has-photo[data-atype="aircraft"] .bh-hero-media { background-image: radial-gradient(130% 100% at 72% 12%, #1b2a37 0%, #0a1017 100%); }
html.skin-balen .bh-hero.bh-has-photo[data-atype="boat"]     .bh-hero-media { background-image: radial-gradient(130% 100% at 72% 12%, #13232f 0%, #08121b 100%); }
html.skin-balen .bh-hero.bh-has-photo[data-atype="home"]     .bh-hero-media { background-image: radial-gradient(130% 100% at 72% 12%, #2a2114 0%, #0e0a06 100%); }
html.skin-balen .bh-hero.bh-has-photo[data-atype="vehicle"]  .bh-hero-media { background-image: radial-gradient(130% 100% at 72% 12%, #1f2226 0%, #0b0e10 100%); }
/* READABILITY OVERLAY over an owner photo = two LOCALIZED bands, never a
   sheet across the photograph (2026-07-26 "the photo is the hero" rework).
   Layer 1 (on top, 135deg) is the TOP-LEFT identity band: it starts at the
   corner where the asset name / model / readiness chip sit (left:20px /
   top:18px) and decays to FULLY TRANSPARENT by 44% of the diagonal -- it
   never reaches the centre of the image.
   Layer 2 (underneath, vertical) is the BOTTOM instrument band: fully
   transparent down to 76% of the height, then a smooth ramp under
   .bh-instruments only (its top edge is ~78% on the 320px hero).
   The CENTRE, RIGHT side and TOP-RIGHT corner of the photo carry NO overlay
   at all, and the image layer itself is unfiltered (see --bh-hero-filter
   above) -- a bright beach house stays bright.
   BOTH layers arrive as ONE custom property, --bh-hero-scrim, which
   js/billy-home.js sets to heroCssVars().scrimLayers verbatim, so the editor
   preview and this hero cannot drift.
   The fallbacks below are dead in normal operation and exist only for the
   no-JS / stale-JS cases, innermost first:
     --bh-ov-gradient  (still written by billy-home.js; the BOTTOM band) keeps
                       an older stylesheet+newer script pairing correct;
     the literal ramp  keeps the localized appearance if js/asset-hero.js
                       never loads at all (kept byte-consistent with the
                       balanced-preset default in js/asset-hero.js).
   Note var(--a, X, Y) takes EVERYTHING after the first comma as the fallback,
   so the two-layer fallback below is a single valid fallback value. */
html.skin-balen .bh-hero.bh-has-photo .bh-hero-scrim { background: var(--bh-hero-scrim,
  linear-gradient(135deg, rgba(8,9,10,0.57) 0%, rgba(8,9,10,0.31) 22%, rgba(8,9,10,0) 44%),
  var(--bh-ov-gradient, linear-gradient(to bottom, rgba(8,9,10,0) 0%, rgba(8,9,10,0) 76%, rgba(8,9,10,0.34) 88%, rgba(8,9,10,0.67) 100%))); }
html.skin-balen .bh-hero-id { position: absolute; left: 20px; top: 18px; z-index: 2; }
html.skin-balen .bh-hero-name { font-size: 24px; line-height: 28px; font-weight: 600; letter-spacing: -0.3px; color: var(--bh-on-photo); }
html.skin-balen .bh-hero-model { font-size: 13px; color: var(--bh-on-photo-2); margin-top: 3px; }
html.skin-balen .bh-state { display: inline-flex; align-items: center; gap: 6px; margin-top: 9px; border-radius: 999px; padding: 3px 10px; background: rgba(255,255,255,0.10); }
html.skin-balen .bh-state .bh-dot { width: 5px; height: 5px; border-radius: 50%; }
html.skin-balen .bh-state-word { font-size: 11px; letter-spacing: 0.3px; }
/* Photo heroes only: a subtle text-shadow carries the tail of a long asset
   name past the 44% end of the localized top-left band (the deliberate
   alternative to widening/darkening the band -- the photo stays the hero).
   Not applied to stock heroes, whose art-directed scrim already covers. */
html.skin-balen .bh-hero.bh-has-photo .bh-hero-name,
html.skin-balen .bh-hero.bh-has-photo .bh-hero-model,
html.skin-balen .bh-hero.bh-has-photo .bh-state-word { text-shadow: 0 1px 2px rgba(0,0,0,0.45), 0 2px 14px rgba(0,0,0,0.35); }

/* readiness panel (replaces the readiness ring; explainable, no scores) */
html.skin-balen .bh-ready-panel { position: absolute; right: 20px; bottom: 74px; z-index: 2; min-width: 190px; max-width: 260px; border-radius: 16px; padding: 14px 16px; background: var(--bh-photo-veil); -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px); box-shadow: inset 0 0 0 1px rgba(255,255,255,0.12), 0 14px 34px rgba(0,0,0,0.42); }
html.skin-balen .bh-ready-head { display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 700; letter-spacing: 0.2px; color: var(--bh-ready); }
html.skin-balen .bh-ready-head.is-attn { color: var(--bh-attn); }
html.skin-balen .bh-ready-head svg { width: 18px; height: 18px; }
html.skin-balen .bh-ready-sub { font-size: 12px; color: var(--bh-on-photo-2); margin-top: 4px; }
html.skin-balen .bh-ready-list { margin-top: 10px; display: flex; flex-direction: column; gap: 5px; }
html.skin-balen .bh-ready-item { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--bh-on-photo-2); }
html.skin-balen .bh-ready-item svg { width: 13px; height: 13px; color: var(--bh-ready); flex-shrink: 0; }

/* carousel arrows (desktop/hover; mobile uses swipe) */
html.skin-balen .bh-arrow { position: absolute; top: 44%; transform: translateY(-50%); z-index: 3; width: 40px; height: 40px; border-radius: 50%; border: none; cursor: pointer; background: rgba(8,9,10,0.45); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); color: var(--bh-on-photo); display: none; align-items: center; justify-content: center; box-shadow: inset 0 0 0 1px rgba(255,255,255,0.14); }
html.skin-balen .bh-arrow svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
html.skin-balen .bh-arrow-prev { left: 14px; }
html.skin-balen .bh-arrow-next { right: 14px; }
@media (hover: hover) and (min-width: 768px) {
  html.skin-balen .bh-arrow { display: flex; opacity: 0; transition: opacity 200ms ease; }
  html.skin-balen .bh-hero:hover .bh-arrow { opacity: 0.9; }
  html.skin-balen .bh-arrow:hover { opacity: 1; background: rgba(8,9,10,0.65); }
}
html.skin-balen .bh-instr.bh-tap:hover .bh-instr-val { color: var(--bh-accent); }

/* instruments (metric row across the hero base)
   CONTRAST CONTRACT (recomputed 2026-07-26 for the localized overlay: NO
   standing image filter, bottom band transparent above 76%). The strip is
   flush at bottom:0 with its own band, on TOP of the scrim, so the band and
   the bottom gradient MULTIPLY. Worst case is a blown-out sky/white fuselage:
   backdrop sRGB 1.0 -- unfiltered now. Gamma-space compositing, measured
   against the real tokens (#F5F5F2 base ink):
     17px values (y ~88%, gradient 0.335): 1-(1-0.335)(1-0.62) = 0.747
       -> v = 0.253, 9.4:1 -- clears the 4.5:1 normal-text bar by 2.1x.
     12px labels (y ~85%, gradient ~0.25, ink 0.72 alpha): composite 0.715
       -> 5.2:1, clears 4.5:1.
     11px subs (y ~92%, ink 0.50 alpha): ~4.1:1. The sub ink caps at 4.9:1
       even on pure black (it is 50%-alpha by design), so this auxiliary
       caption tier is accepted at large-text-threshold contrast rather than
       darkening the whole strip further.
   The band was 0.5 when the full-height scrim + brightness(0.82) filter
   stood behind it; 0.62 restores the SAME effective ink contrast now that
   the strip is the only dark thing at the hero's base. It covers only the
   strip's own height -- the photograph above it is untouched.
   If this band is ever lowered, re-run this arithmetic. */
html.skin-balen .bh-instruments { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; background: rgba(8,9,10,0.62); display: flex; overflow-x: auto; overflow-y: hidden; padding: 12px 20px; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
html.skin-balen .bh-instruments::-webkit-scrollbar { display: none; }
html.skin-balen .bh-instr { min-width: 96px; flex-shrink: 0; padding-right: 16px; }
html.skin-balen .bh-instr + .bh-instr { border-left: 0.5px solid rgba(255,255,255,0.10); padding-left: 16px; }
html.skin-balen .bh-instr-label { font-size: 12px; letter-spacing: 0.6px; color: var(--bh-on-photo-2); text-transform: uppercase; }
html.skin-balen .bh-instr-val { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 17px; line-height: 22px; color: var(--bh-on-photo); margin-top: 4px; font-weight: 500; }
html.skin-balen .bh-instr-sub { font-size: 11px; color: var(--bh-on-photo-3); margin-top: 2px; }
/* Caption tier for the KPI cards. .bh-instr-sub is an OVER-THE-PHOTO class
   (--bh-on-photo-3 is fixed light ink), and the Fuel Cost / Hour card reused
   it while sitting on an ordinary panel. On Midnight that panel is dark so it
   looked right; on Air the panel is white, and the caption was light-on-white
   -- invisible. --bh-caption resolves to the SAME value as --bh-on-photo-3
   under Midnight, so Midnight is byte-identical, and to a readable slate
   under Air. */
html.skin-balen .bh-kpi-sub { font-size: 11px; color: var(--bh-caption); margin-top: 2px; }

html.skin-balen .bh-underhero { display: flex; align-items: center; gap: 8px; padding: 12px 20px 0; }
html.skin-balen .bh-underhero-meta { font-size: 12px; color: var(--bh-text-3); }
html.skin-balen .bh-dots { display: flex; gap: 5px; margin-left: auto; }
html.skin-balen .bh-dots > span { width: 5px; height: 5px; border-radius: 50%; background: var(--bh-text-3); opacity: 0.4; }
html.skin-balen .bh-dots > span.on { background: var(--bh-text); opacity: 1; }

/* ---- panels / rows (glass) ---------------------------------------- */
html.skin-balen .bh-section { padding: 24px 20px 0; }
html.skin-balen .bh-section-label { font-size: 13px; line-height: 16px; letter-spacing: 1.2px; text-transform: uppercase; color: var(--bh-text-2); font-weight: 600; }
html.skin-balen .bh-panel {
  margin-top: 12px; border-radius: 20px; background: var(--bh-glass);
  -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px);
  box-shadow: var(--bh-panel-shadow); overflow: hidden;
}
html.skin-balen .bh-row { display: flex; align-items: center; gap: 12px; padding: 14px 16px; }
html.skin-balen .bh-row + .bh-row { border-top: 0.5px solid var(--bh-hairline); }
html.skin-balen .bh-row .bh-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
html.skin-balen .bh-row-text { flex: 1; font-size: 16px; color: var(--bh-text); }
html.skin-balen .bh-row-val { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 16px; color: var(--bh-text); }
html.skin-balen .bh-row-chev { color: var(--bh-text-3); display: inline-flex; }
html.skin-balen .bh-row-chev svg { width: 14px; height: 14px; }
html.skin-balen .bh-empty { padding: 18px 16px; font-size: 16px; color: var(--bh-text-2); font-family: var(--font-serif); }

/* CTA link */
html.skin-balen .bh-cta { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; font-size: 14px; color: var(--bh-accent); cursor: pointer; border-top: 0.5px solid var(--bh-hairline); }
html.skin-balen .bh-cta svg { width: 14px; height: 14px; }

/* KPI grid (What this asset costs you) */
html.skin-balen .bh-kpi-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px 18px; padding: 22px 20px; }
html.skin-balen .bh-kpi-label { font-size: 12px; letter-spacing: 0.4px; color: var(--bh-text-2); text-transform: uppercase; }
html.skin-balen .bh-kpi-val { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 26px; line-height: 30px; color: var(--bh-text); margin-top: 8px; font-weight: 600; }
html.skin-balen .bh-kpi-val.pos { color: var(--bh-ready-s); }
html.skin-balen .bh-kpi-val.neg { color: var(--bh-action-s); }

/* By-partner breakdown (same canonical attribution as the KPI tiles above).
   Deliberately SUBORDINATE to the four combined KPI tiles: smaller radius than
   the 20px panel, no drop shadow, 10px uppercase metric labels and 13px mono
   values against the 26px KPI values. A hairline rule separates the block. */
html.skin-balen .bh-partners { padding: 16px 20px 18px; border-top: 0.5px solid var(--bh-hairline); }
html.skin-balen .bh-partners-label { font-size: 10px; letter-spacing: 1px; text-transform: uppercase; color: var(--bh-text-3); font-weight: 600; margin-bottom: 10px; }
html.skin-balen .bh-pcards { display: grid; grid-template-columns: 1fr; gap: 10px; align-items: stretch; }
/* the inset hairline is the card's structure; the tint is an enhancement only,
   so the card stays visible where color-mix() is unsupported */
html.skin-balen .bh-pcard {
  display: flex; flex-direction: column; gap: 8px; height: 100%; min-width: 0;
  padding: 10px 12px; border-radius: 12px;
  background: transparent;
  background: color-mix(in srgb, var(--bh-text) 4%, transparent);
  box-shadow: inset 0 0 0 1px var(--bh-glass-edge);
}
html.skin-balen .bh-pcard-head { min-width: 0; }
html.skin-balen .bh-pcard-name { display: block; font-size: 13px; font-weight: 600; color: var(--bh-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html.skin-balen .bh-pcard-metrics { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; flex: 1; align-items: start; }
html.skin-balen .bh-pmetric { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* The label reserves TWO lines whatever it actually needs, so the three amounts
   sit on one baseline even when only one label wraps ("OWNERSHIP COST" beside
   "BUSINESS", or the Spanish titles). Without it a single wrapped label dropped
   its own amount ~12px below its neighbours at every breakpoint. Reserving the
   space on the LABEL (rather than bottom-aligning the values) also keeps the
   amounts aligned when a dual-currency value itself wraps to two lines. */
html.skin-balen .bh-pmetric-label { font-size: 10px; line-height: 12px; min-height: 24px; letter-spacing: 0.5px; text-transform: uppercase; color: var(--bh-text-3); font-weight: 500; overflow-wrap: anywhere; }
/* dual-currency values ("Q4,758.93 + $550.00") wrap inside the cell, never
   widen the card or scroll the page sideways */
html.skin-balen .bh-pmetric-val { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 13px; line-height: 16px; color: var(--bh-text-2); min-width: 0; overflow-wrap: anywhere; word-break: break-word; }
html.skin-balen .bh-pmetric-val.pos { color: var(--bh-ready-s); }
html.skin-balen .bh-pmetric-val.zero { color: var(--bh-text-3); opacity: 0.6; }
/* EMPTY MONTH (A5): the cards still render - the partner roster is
   period-independent - but a block of pure em-dashes must not out-shout the
   four KPI tiles it sits under, directly below "No activity recorded for this
   month.". Compact variant only: same cards, same honest em-dash values. */
html.skin-balen .bh-partners.is-empty { padding: 10px 20px 12px; }
html.skin-balen .bh-partners.is-empty .bh-partners-label { margin-bottom: 6px; }
html.skin-balen .bh-partners.is-empty .bh-pcards { gap: 6px; }
html.skin-balen .bh-partners.is-empty .bh-pcard { gap: 4px; padding: 6px 10px; border-radius: 10px; background: transparent; box-shadow: inset 0 0 0 1px var(--bh-hairline); }
html.skin-balen .bh-partners.is-empty .bh-pcard-name { font-size: 12px; font-weight: 500; color: var(--bh-text-2); }
html.skin-balen .bh-partners.is-empty .bh-pcard-metrics { gap: 6px; }
html.skin-balen .bh-partners.is-empty .bh-pmetric { gap: 0; }
html.skin-balen .bh-partners.is-empty .bh-pmetric-label { font-size: 9px; line-height: 11px; min-height: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.skin-balen .bh-partners.is-empty .bh-pmetric-val { font-size: 12px; line-height: 14px; }

/* narrow phones: the 3-up metric row gets cramped, stack label/value pairs */
@media (max-width: 380px) {
  html.skin-balen .bh-pcard-metrics { grid-template-columns: 1fr; gap: 6px; }
  html.skin-balen .bh-pmetric { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 10px; }
  /* label and value share a baseline here, so the reserved 2-line block is
     neither needed nor wanted */
  html.skin-balen .bh-pmetric-label { min-height: 0; }
  html.skin-balen .bh-pmetric-val { text-align: right; }
}
@media (min-width: 768px) {
  html.skin-balen .bh-pcards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Wide screens: size the cards from the PARTNER COUNT, not the container.
   auto-fill built 4 tracks at 1440px, so a 2-partner asset (every asset on
   staging has 2-3 partners) filled 2 of them and left ~50% dead space, reading
   as a truncated grid. Flex lets 2 or 3 cards share the full row and still
   wraps at 240px once a partnership is genuinely large. */
@media (min-width: 1200px) {
  html.skin-balen .bh-pcards { display: flex; flex-wrap: wrap; }
  html.skin-balen .bh-pcard { flex: 1 1 240px; max-width: 100%; }
}

/* card header with compact prev/next month navigator */
html.skin-balen .bh-section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
html.skin-balen .bh-month-nav { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; }
html.skin-balen .bh-mbtn { width: 28px; height: 28px; border-radius: 8px; border: none; cursor: pointer; padding: 0; background: var(--bh-glass); box-shadow: inset 0 0 0 1px var(--bh-glass-edge); color: var(--bh-text-2); display: inline-flex; align-items: center; justify-content: center; }
html.skin-balen .bh-mbtn svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
html.skin-balen .bh-mbtn:hover:not([disabled]) { color: var(--bh-text); }
html.skin-balen .bh-mbtn[disabled] { opacity: 0.35; cursor: not-allowed; }
html.skin-balen .bh-month-lbl { min-width: 96px; text-align: center; font-size: 13px; font-weight: 600; color: var(--bh-text); font-variant-numeric: tabular-nums; }
html.skin-balen #bh-costs .bh-panel { transition: opacity 140ms ease; }
html.skin-balen #bh-costs.bh-refreshing .bh-panel { opacity: 0.5; }

/* balances + exchange rows */
html.skin-balen .bh-balrow, html.skin-balen .bh-xrow { display: flex; align-items: center; gap: 12px; padding: 14px 18px; }
html.skin-balen .bh-balrow + .bh-balrow, html.skin-balen .bh-xrow + .bh-xrow { border-top: 0.5px solid var(--bh-hairline); }
html.skin-balen .bh-bal-name, html.skin-balen .bh-x-partner { flex: 1; font-size: 15px; color: var(--bh-text); }
html.skin-balen .bh-bal-role { font-size: 11px; color: var(--bh-text-3); text-transform: uppercase; letter-spacing: 0.4px; margin-left: 8px; }
html.skin-balen .bh-bal-val, html.skin-balen .bh-x-net { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 15px; color: var(--bh-text); }
html.skin-balen .bh-bal-val.neg, html.skin-balen .bh-x-net.neg { color: var(--bh-action-s); }
html.skin-balen .bh-x-net.pos { color: var(--bh-ready-s); }
html.skin-balen .bh-x-status { font-size: 11px; color: var(--bh-text-2); text-transform: uppercase; letter-spacing: 0.4px; min-width: 64px; text-align: right; }

/* money figure */
html.skin-balen .bh-money { padding: 18px; }
html.skin-balen .bh-money-label { font-size: 12px; letter-spacing: 0.6px; color: var(--bh-text-2); text-transform: uppercase; }
html.skin-balen .bh-money-fig { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 40px; line-height: 46px; color: var(--bh-text); margin-top: 6px; font-weight: 600; }
html.skin-balen .bh-money-fig.neg { color: var(--bh-action-s); }
html.skin-balen .bh-money-foot { display: flex; align-items: flex-end; justify-content: space-between; margin-top: 8px; }
html.skin-balen .bh-money-delta { font-family: var(--font-mono); font-size: 12px; color: var(--bh-text-2); }

/* timeline rails */
html.skin-balen .bh-rail { padding: 6px 16px 12px; }
html.skin-balen .bh-rail-item { display: flex; gap: 14px; padding: 10px 0; align-items: baseline; }
html.skin-balen .bh-rail-item + .bh-rail-item { border-top: 0.5px solid var(--bh-hairline); }
html.skin-balen .bh-rail-when { font-family: var(--font-mono); font-size: 12px; color: var(--bh-text-2); min-width: 62px; }
html.skin-balen .bh-rail-what { font-size: 15px; color: var(--bh-text); }
html.skin-balen .bh-rail.past .bh-rail-what { color: var(--bh-text-2); }

/* ---- the Float: nav + red ignition -------------------------------- */
html.skin-balen .bh-nav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: var(--bh-nav-bg); -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px);
  border-top: 0.5px solid var(--bh-glass-edge);
  padding: 12px 26px calc(12px + env(safe-area-inset-bottom, 6px));
  display: flex; justify-content: space-between; align-items: center;
}
html.skin-balen .bh-navbtn { background: none; border: none; padding: 6px 8px; color: var(--bh-text-3); display: flex; flex-direction: column; align-items: center; gap: 4px; cursor: pointer; min-width: 44px; min-height: 44px; justify-content: center; position: relative; }
html.skin-balen .bh-navbtn svg { width: 22px; height: 22px; }
html.skin-balen .bh-navbtn.on { color: var(--bh-accent); }
html.skin-balen .bh-navtick { width: 16px; height: 2px; border-radius: 1px; background: transparent; }
html.skin-balen .bh-navbtn.on .bh-navtick { background: var(--bh-ignition); }
html.skin-balen .bh-nav-gap { width: 56px; flex-shrink: 0; }
html.skin-balen .bh-ignition {
  position: fixed; left: 50%; bottom: calc(30px + env(safe-area-inset-bottom, 6px)); transform: translateX(-50%);
  z-index: 41; width: 60px; height: 60px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--bh-ignition); box-shadow: 0 12px 30px color-mix(in srgb, var(--bh-ignition) 45%, transparent), 0 2px 6px rgba(0,0,0,0.4);
  display: flex; align-items: center; justify-content: center;
}
html.skin-balen .bh-ignition::after { content: ""; position: absolute; inset: 4px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.22); }
html.skin-balen .bh-ignition svg { width: 24px; height: 24px; color: #fff; position: relative; }
html.skin-balen .bh-ignition:active { transform: translateX(-50%) translateY(2px); }

/* reused Classic profile dropdown, re-clothed for Balen */
html.skin-balen #bh-menu-overlay .org-dd { background: var(--bh-menu-bg); color: var(--bh-text); box-shadow: inset 0 0 0 0.5px var(--bh-glass-edge), 0 24px 60px rgba(0,0,0,0.35); }
html.skin-balen #bh-menu-overlay .org-dd-item { color: var(--bh-text); }
html.skin-balen #bh-menu-overlay .org-dd-item.active { background: color-mix(in srgb, var(--bh-text) 6%, transparent); }

/* ---- motion (subtle) ---------------------------------------------- */
@keyframes bh-breathe { 0%,100% { opacity: 0.9; } 50% { opacity: 1; } }
@keyframes bh-rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
/* The entry animation animates the SAME transform property the owner crop
   uses, so it must be expressed relative to --bh-hero-zoom or it would snap
   the photo back to scale 1 on every render. With no crop (--bh-hero-zoom
   unset -> 1) this is identical to the original 1.03 -> 1 push-in. */
@keyframes bh-hero-in { from { opacity: 0; transform: scale(calc(var(--bh-hero-zoom, 1) * 1.03)); } to { opacity: 1; transform: scale(var(--bh-hero-zoom, 1)); } }
html.skin-balen .bh-header  { animation: bh-rise 0.5s cubic-bezier(0.22,1,0.36,1) both; }
html.skin-balen .bh-copilot { animation: bh-rise 0.5s cubic-bezier(0.22,1,0.36,1) 0.06s both; }
html.skin-balen #bh-heroregion { animation: bh-rise 0.6s cubic-bezier(0.22,1,0.36,1) 0.12s both; }
html.skin-balen .bh-fin, html.skin-balen .bh-deck { animation: bh-rise 0.6s cubic-bezier(0.22,1,0.36,1) 0.18s both; }
html.skin-balen .bh-hero-media { animation: bh-hero-in 0.7s cubic-bezier(0.22,1,0.36,1) both; }
html.skin-balen .bh-panel { transition: transform 320ms cubic-bezier(0.22,1,0.36,1), box-shadow 320ms cubic-bezier(0.22,1,0.36,1); }
@media (hover: hover) {
  html.skin-balen .bh-panel:hover { transform: translateY(-3px); box-shadow: inset 0 0 0 1px var(--bh-hover-edge), 0 26px 64px rgba(0,0,0,0.30); }
  html.skin-balen .bh-navbtn:hover { color: var(--bh-text); }
  html.skin-balen .bh-ignition { transition: transform 200ms cubic-bezier(0.34,1.2,0.44,1), box-shadow 200ms ease; }
  html.skin-balen .bh-ignition:hover { transform: translateX(-50%) translateY(-2px); }
}
@media (prefers-reduced-motion: reduce) {
  html.skin-balen .bh-header, html.skin-balen .bh-copilot, html.skin-balen #bh-heroregion,
  html.skin-balen .bh-fin, html.skin-balen .bh-deck, html.skin-balen .bh-hero-media { animation: none; }
  html.skin-balen .bh-panel { transition: none; }
}

/* ===================================================================
   TABLET (768-1199): wide hero + 2-col decks, bottom nav
   =================================================================== */
@media (min-width: 768px) {
  html.skin-balen .bh-stage { max-width: 1024px; margin: 0 auto; padding: 0 32px; }
  html.skin-balen .bh-header, html.skin-balen .bh-copilot, html.skin-balen .bh-section { padding-left: 0; padding-right: 0; }
  html.skin-balen .bh-status { font-size: 44px; line-height: 50px; }
  html.skin-balen .bh-hero { margin-top: 24px; height: 400px; border-radius: 28px; }
  html.skin-balen .bh-ready-panel { right: 26px; bottom: 84px; }
  html.skin-balen .bh-kpi-grid { grid-template-columns: repeat(4, 1fr); }
  html.skin-balen .bh-fin-row { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; align-items: start; }
  html.skin-balen .bh-deck { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 24px; }
  html.skin-balen .bh-section { padding-top: 28px; }
}

/* ===================================================================
   DESKTOP (>=1200): three-column command center, left glass rail
   =================================================================== */
@media (min-width: 1200px) {
  html.skin-balen .bh-root { padding-left: 88px; padding-bottom: 48px; }
  html.skin-balen .bh-nav {
    top: 0; bottom: 0; right: auto; width: 88px; height: 100vh;
    flex-direction: column; justify-content: flex-start; gap: 6px;
    padding: 26px 0; border-top: none; border-right: 0.5px solid var(--bh-glass-edge);
  }
  html.skin-balen .bh-nav-gap { display: none; }
  html.skin-balen .bh-navbtn { width: 100%; }
  html.skin-balen .bh-navbtn .bh-navtick { display: none; }
  html.skin-balen .bh-navbtn.on { box-shadow: inset 3px 0 0 var(--bh-ignition); }
  html.skin-balen .bh-ignition { left: 44px; bottom: 30px; top: auto; transform: translateX(-50%); width: 56px; height: 56px; }

  html.skin-balen .bh-stage { max-width: 1440px; margin: 0 auto; padding: 44px 48px 0; }
  html.skin-balen .bh-header { padding: 0; }
  html.skin-balen .bh-status { font-size: 56px; line-height: 60px; letter-spacing: -1px; margin-top: 8px; }
  html.skin-balen .bh-copilot { padding: 16px 0 0; font-size: 18px; line-height: 26px; max-width: 900px; }

  html.skin-balen .bh-hero { margin-top: 32px; height: 520px; border-radius: 28px; }
  html.skin-balen .bh-hero-id { left: 32px; top: 30px; }
  html.skin-balen .bh-hero-name { font-size: 34px; line-height: 38px; }
  html.skin-balen .bh-hero-model { font-size: 15px; }
  html.skin-balen .bh-ready-panel { right: 40px; bottom: 120px; min-width: 230px; padding: 18px 20px; }
  html.skin-balen .bh-ready-head { font-size: 17px; }
  html.skin-balen .bh-instruments { overflow: visible; padding: 18px 32px; }
  html.skin-balen .bh-instr { flex: 1 1 0; min-width: 0; }
  html.skin-balen .bh-instr-val { font-size: 20px; line-height: 24px; }
  html.skin-balen .bh-underhero { padding: 14px 4px 0; }

  html.skin-balen .bh-fin-row { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; align-items: start; margin-top: 24px; }
  html.skin-balen .bh-deck { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 24px; align-items: start; margin-top: 24px; }
  html.skin-balen .bh-section { padding: 0; margin-top: 24px; }
  html.skin-balen .bh-money-fig { font-size: 34px; line-height: 40px; }
}

@media (min-width: 1500px) {
  html.skin-balen .bh-hero { height: 560px; }
  html.skin-balen .bh-status { font-size: 60px; }
}
