/* Training companion — sprite-based pixel character and pictures of Lumi / Rooty, shown in two presentations that
 * share markup and canvas logic (companion-device.js):
 *   .companion-device     — the full "training link" handheld, /Progression/Companion only.
 *   .companion-card       — the companion's own card on the athlete dashboard, under / beside the greeting card.
 * Both are BLACK (05 Oct 2026): the pictures come on a black background, so on a black screen they stand without a box
 * around them, and the text on it is colourful: one colour per sport, one per form, one per number.
 */

/* ── Colours, shared by both ─────────────────────────────────────────────────────────────── */

.companion-device,
.companion-card {
    --c-lime: #d8ff54;      /* level; the UTLC accent (the evolve glow is the same lime) */
    --c-cyan: #38bdf8;
    --c-amber: #fbbf24;     /* XP */
    --c-green: #4ade80;
    --c-coral: #ff7a59;     /* the brand's coral heart: the streak */
    --c-ink: #f8fafc;       /* main text on black */
    --c-dim: #8b9ab3;       /* labels */
    --c-faint: #55657f;     /* separators */
    --c-note: #a5b4fc;      /* the companion's own words */
    --sp: #4ade80;          /* sport colour (follows data-sport, which the sport buttons change) */
    --sp-glow: rgba(74, 222, 128, .45);
    --stage: #8b9ab3;       /* form colour (follows data-stage) */
}
[data-companion][data-sport="swim"]     { --sp: #22d3ee; --sp-glow: rgba(34, 211, 238, .45); }
[data-companion][data-sport="bike"]     { --sp: #fbbf24; --sp-glow: rgba(251, 191, 36, .45); }
[data-companion][data-sport="run"]      { --sp: #4ade80; --sp-glow: rgba(74, 222, 128, .45); }
[data-companion][data-sport="strength"] { --sp: #c084fc; --sp-glow: rgba(192, 132, 252, .45); }
[data-companion][data-art-state="rest"]  { --sp: #cbd5e1; --sp-glow: rgba(203, 213, 225, .4); }   /* the Rest Day preview: calm slate, not the last sport's colour */
[data-companion][data-art-state="freestyle"] { --sp: #f472b6; --sp-glow: rgba(244, 114, 182, .45); }   /* Free Style: pink */
[data-companion][data-stage="starter"]   { --stage: #94a3b8; }
[data-companion][data-stage="active"]    { --stage: #60a5fa; }
[data-companion][data-stage="trained"]   { --stage: #a3e635; }
[data-companion][data-stage="endurance"] { --stage: #fb923c; }
[data-companion][data-stage="elite"]     { --stage: #fb7185; }
[data-companion][data-stage="master"]    { --stage: #e879f9; }
/* the top form is not one colour but all of them */
[data-companion][data-stage="master"] .cd-stage strong,
[data-companion][data-stage="master"] .cd-title-stage,
[data-companion][data-stage="master"] .companion-card-stage {
    background: linear-gradient(90deg, #fbbf24, #fb7185, #e879f9, #60a5fa, #22d3ee);
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent; color: transparent;
}

/* ── Full device (Companion detail page) ─────────────────────────────────────────────────── */

.companion-device {
    --cd-rim: #38bdf8;      /* case accent (rim glow, signal dots) */
    width: min(100%, 300px);
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    color: var(--c-dim);
}

.companion-device .cd-case {
    position: relative;
    border: 1px solid rgba(56, 189, 248, .35);
    border-radius: 26px;
    padding: 10px;
    background: linear-gradient(160deg, #161d2c, #05070b 70%);
    box-shadow:
        0 20px 50px rgba(0, 0, 0, .55),
        0 0 0 1px rgba(56, 189, 248, .12),
        0 0 24px rgba(56, 189, 248, .12),
        inset 0 1px rgba(255, 255, 255, .08);
}
/* Faint top sheen — the one "glossy" touch that keeps the case from reading flat-matte */
.companion-device .cd-case::before {
    content: "";
    position: absolute; inset: 1px 1px auto 1px; height: 40%;
    border-radius: 25px 25px 60% 60% / 25px 25px 30px 30px;
    background: linear-gradient(180deg, rgba(255, 255, 255, .06), transparent);
    pointer-events: none;
}

.companion-device .cd-header,
.companion-device .cd-footer {
    position: relative; z-index: 1;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 2px 6px 8px;
    font-size: 9px;
    letter-spacing: .12em;
    color: var(--c-dim);
}
.companion-device .cd-footer { padding: 8px 6px 2px; }
.companion-device .cd-brand { color: var(--c-lime); font-weight: 700; }
.companion-device .cd-signal { display: inline-flex; align-items: center; gap: 3px; }
.companion-device .cd-signal i { display: block; width: 5px; height: 9px; border-radius: 1px; }
.companion-device .cd-signal i:nth-child(1) { background: var(--c-cyan);  box-shadow: 0 0 6px rgba(56, 189, 248, .7); }
.companion-device .cd-signal i:nth-child(2) { background: var(--c-lime);  box-shadow: 0 0 6px rgba(216, 255, 84, .7); }
.companion-device .cd-signal i:nth-child(3) { background: var(--c-amber); box-shadow: 0 0 6px rgba(251, 191, 36, .7); }
.companion-device .cd-key { font-weight: 700; }
.companion-device .cd-key--streak { color: var(--c-coral); }
.companion-device .cd-key--best { color: var(--c-cyan); }
.companion-device .cd-footer strong { color: var(--c-ink); }

.companion-device .cd-lcd {
    position: relative;
    overflow: hidden;
    border: 5px solid #05070b;
    border-radius: 14px;
    padding: 12px;
    background: #000;                    /* the pictures come on black: on a black screen nothing boxes them in */
    color: var(--c-ink);
    box-shadow: inset 0 0 26px rgba(56, 189, 248, .08), 0 0 0 2px #1c2433;
}

.companion-device .cd-level-row {
    position: relative; z-index: 1;
    display: flex; justify-content: space-between; align-items: flex-start;
}
.companion-device .cd-level-row small { display: block; font-size: 8px; letter-spacing: .16em; color: var(--c-dim); }
.companion-device .cd-level-row strong { font-size: 22px; line-height: 1; }
.companion-device .cd-level strong { color: var(--c-lime); text-shadow: 0 0 14px rgba(216, 255, 84, .35); }
.companion-device .cd-stage { text-align: right; }
.companion-device .cd-stage strong { font-size: 12px; color: var(--stage); }

.companion-device canvas {
    display: block;
    width: min(48vw, 176px); height: min(48vw, 176px);
    max-width: 176px; max-height: 176px;
    margin: -2px auto 10px;
    image-rendering: pixelated;
    border-radius: 6px;
}

.companion-device h5.cd-title {
    position: relative; z-index: 1; margin: 0; min-height: 16px;
    text-align: center; font-size: 12px; line-height: 1.2; letter-spacing: .08em; font-weight: 700;
    color: var(--c-ink);
}
.companion-device .cd-title-sport { color: var(--sp); text-shadow: 0 0 10px var(--sp-glow); }
.companion-device .cd-title-sep { color: var(--c-faint); }
.companion-device .cd-title-stage { color: var(--stage); }
.companion-device .cd-message {
    position: relative; z-index: 1; min-height: 22px; margin: 5px 0 10px;
    text-align: center; font-size: 9px; color: var(--c-note);
}

.companion-device .cd-xp-label { position: relative; z-index: 1; display: flex; justify-content: space-between; font-size: 9px; font-weight: bold; }
.companion-device .cd-xp-label span:first-child { color: var(--c-amber); }
.companion-device .cd-xp-label span:last-child { color: var(--c-ink); }
.companion-device .cd-xp-track { position: relative; z-index: 1; height: 10px; margin-top: 4px; border: 2px solid #334155; background: #0b1220; padding: 1px; border-radius: 4px; }
.companion-device .cd-xp-track span {
    display: block; height: 100%; border-radius: 2px;
    background: linear-gradient(90deg, var(--c-cyan), var(--c-green) 45%, var(--c-lime) 72%, var(--c-amber));
    box-shadow: 0 0 8px rgba(216, 255, 84, .3);
    transition: width .35s ease;
}

.companion-device .cd-today { position: relative; z-index: 1; display: flex; justify-content: space-between; gap: 4px; margin-top: 10px; font-size: 7.5px; font-weight: bold; }
.companion-device .cd-today span { color: var(--c-dim); opacity: .7; }
.companion-device .cd-today .cd-done { opacity: 1; color: var(--c-green); }

@media (max-width: 420px) {
    .companion-device { width: 100%; }
}

/* Large variant — the dedicated companion detail page. Today's checklist doesn't apply there
 * (it's a profile view, not "today"), so it's hidden rather than shown as three false checks. */
.companion-device--large { width: min(100%, 420px); }
.companion-device--large canvas {
    width: min(70vw, 256px); height: min(70vw, 256px); max-width: 256px; max-height: 256px;
}
.companion-device--large .cd-level-row strong { font-size: 30px; }
.companion-device--large h5.cd-title { font-size: 15px; }
.companion-device--large .cd-message { font-size: 11px; min-height: 26px; }
.companion-device--large .cd-today { display: none; }

/* Sport switcher — large variant only (see the button row in _TrainingCompanion.cshtml). Lets
 * the athlete preview the companion in another sport's pose set without leaving the page; the
 * sheet already has all 4 sports as rows, so switching is a client-side redraw, no reload.
 * Each button carries its sport's colour: an outline while it waits, filled and glowing while it is the one showing. */
.companion-device [data-companion-sport-btn="swim"]     { --sp: #22d3ee; --sp-glow: rgba(34, 211, 238, .45); }
.companion-device [data-companion-sport-btn="bike"]     { --sp: #fbbf24; --sp-glow: rgba(251, 191, 36, .45); }
.companion-device [data-companion-sport-btn="run"]      { --sp: #4ade80; --sp-glow: rgba(74, 222, 128, .45); }
.companion-device [data-companion-sport-btn="strength"] { --sp: #c084fc; --sp-glow: rgba(192, 132, 252, .45); }
.companion-device [data-companion-sport-btn="rest"]     { --sp: #cbd5e1; --sp-glow: rgba(203, 213, 225, .4); }
.companion-device [data-companion-sport-btn="freestyle"] { --sp: #f472b6; --sp-glow: rgba(244, 114, 182, .45); }
.companion-device--large .cd-sport-switch {
    position: relative; z-index: 1;
    display: flex; justify-content: center; gap: 4px; margin: -2px 0 6px;
}
.companion-device--large .cd-sport-btn {
    flex: 1; max-width: 64px;
    padding: 3px 0;
    border: 1.5px solid var(--sp);
    border-radius: 4px;
    background: transparent;
    color: var(--sp);
    font-family: inherit;
    font-size: 8px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    cursor: pointer;
    opacity: .6;
    transition: opacity .15s ease, background-color .15s ease, color .15s ease, box-shadow .15s ease;
}
.companion-device--large .cd-sport-btn:hover { opacity: .9; }
.companion-device--large .cd-sport-btn.active {
    opacity: 1;
    background: var(--sp);
    color: #000;
    box-shadow: 0 0 10px var(--sp-glow);
}

/* ── Companion card (athlete dashboard) ──────────────────────────────────────────────────── *
 * Until 05 Oct 2026 the companion was a 66x88 thumbnail inside the greeting card, too small to make out on a phone. It has
 * a card of its own now (the dashboard stacks it under the greeting card on a phone and puts it beside it on a wide
 * screen): the picture as big as the width allows, the level beside it, the whole card the link to the Companion page. */

.companion-card-link {
    display: block; height: 100%;
    text-decoration: none; color: inherit;
    border-radius: 16px;
    transition: transform .15s ease;
}
.companion-card-link:hover { transform: translateY(-1px); }
.companion-card-link:focus-visible { outline: 2px solid #38bdf8; outline-offset: 3px; }

.companion-card {
    --card-frame-h: min(46vw, 200px);    /* the picture's height: 46% of the screen's width, up to 200 px (3:4 like every frame) */
    display: flex; align-items: center; gap: 1rem;
    height: 100%;
    padding: 1rem 1.1rem;
    border: 1px solid rgba(56, 189, 248, .3);
    border-radius: 16px;
    background: #000;
    color: var(--c-ink);
    box-shadow: 0 0 22px rgba(56, 189, 248, .1), inset 0 0 22px rgba(56, 189, 248, .06);
}
.companion-card-canvas {
    width: calc(var(--card-frame-h) * .75); height: calc(var(--card-frame-h) * .75);   /* the sprite's stand-in for the frame */
    flex-shrink: 0;
    image-rendering: pixelated;
}
.companion-card-body { flex: 1; min-width: 0; }
.companion-card-stage { font-size: .72rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--stage); }
.companion-card-level { font-size: 2.1rem; font-weight: 800; line-height: 1.05; color: var(--c-lime); text-shadow: 0 0 16px rgba(216, 255, 84, .35); }
.companion-card-bar { height: 10px; margin: .45rem 0 .3rem; padding: 1px; border: 2px solid #334155; border-radius: 5px; background: #0b1220; }
.companion-card-bar span {
    display: block; height: 100%; border-radius: 3px;
    background: linear-gradient(90deg, var(--c-cyan), var(--c-green) 45%, var(--c-lime) 72%, var(--c-amber));
    box-shadow: 0 0 8px rgba(216, 255, 84, .3);
}
.companion-card-xp { font-size: .75rem; color: var(--c-ink); font-variant-numeric: tabular-nums; }
.companion-card-streak { margin-top: .25rem; font-size: .8rem; font-weight: 600; color: var(--c-coral); }
.companion-card-message { margin-top: .4rem; font-size: .75rem; line-height: 1.3; color: var(--c-note); }
.companion-card-more { margin-top: .5rem; font-size: .75rem; font-weight: 600; color: var(--c-cyan); }

/* ── Pictures of Lumi (girl) and Rooty (boy), 05 Oct 2026 ────────────────────────────────────
 * Where a sport has a picture (Helpers/CompanionArt) it is shown in this frame instead of the sprite canvas
 * (companion-device.js hides one and shows the other). The pictures come on a flat black background and are used as
 * they are, so the frame is black; it takes the box of the canvas it stands in for.
 * A still picture gets a little motion from here, at the tempo the sprite loop had: a stride in .68 s while training,
 * a hop in .92 s when celebrating or evolving, a slow breath otherwise. A GIF (data-motion="none") just plays. */
.companion-art-frame[hidden],
.companion-device canvas[hidden],
.companion-card canvas[hidden] { display: none !important; }

/* EVERY picture gets the same frame, 3:4 (CompanionArt.FrameAspect), so the box is the same size whatever the activity.
 * The picture is fitted inside at its own shape: --art-w / --art-h (set inline, from its pixel size) are its width and
 * height as shares of the frame's, and --art-feather fades its sides into the frame's black where it does not reach them
 * (the bike clips are shot on a dark studio floor, not pure black, so they would otherwise end in a faint vertical edge). */
.companion-art-frame {
    --cd-cycle: 1.92s;
    --art-w: 1; --art-h: 1; --art-feather: 0%;
    --frame-h: min(48vw, 176px);
    position: relative;
    flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    overflow: hidden;
    background: #000;
    height: var(--frame-h); width: calc(var(--frame-h) * .75);
    margin: -2px auto 10px;
    border-radius: 8px;
}
.companion-device--large .companion-art-frame { --frame-h: min(70vw, 256px); }
.companion-card .companion-art-frame { --frame-h: var(--card-frame-h); margin: 0; border-radius: 12px; }

.companion-art-frame picture { display: contents; }
.companion-art {
    display: block; flex: none;
    width: calc(var(--art-w) * 100%); height: calc(var(--art-h) * 100%);
    object-fit: contain;
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--art-feather), #000 calc(100% - var(--art-feather)), transparent 100%);
    mask-image: linear-gradient(to right, transparent 0, #000 var(--art-feather), #000 calc(100% - var(--art-feather)), transparent 100%);
    transform-origin: 50% 94%;          /* the feet: squash and lean pivot on the ground */
    user-select: none; -webkit-user-drag: none;
}
/* A still moves, so it needs headroom for the hop (the picture is drawn tight to its top edge); an animation does not. */
.companion-art[data-motion="bob"] { box-sizing: border-box; padding: 9% 0 2%; animation: companion-art-breathe var(--cd-cycle) ease-in-out infinite; }

[data-companion][data-state="train"] .companion-art-frame { --cd-cycle: .68s; }
[data-companion][data-state="celebrate"] .companion-art-frame,
[data-companion][data-state="evolve"] .companion-art-frame { --cd-cycle: .92s; }
[data-companion][data-state="train"] .companion-art[data-motion="bob"] { animation-name: companion-art-run; animation-timing-function: linear; }
[data-companion][data-state="celebrate"] .companion-art[data-motion="bob"],
[data-companion][data-state="evolve"] .companion-art[data-motion="bob"] { animation-name: companion-art-hop; animation-timing-function: linear; }

/* The sprite tinted the whole canvas lime while evolving; the frame does the same, pulsing with the hop. */
[data-companion][data-state="evolve"] .companion-art-frame::after {
    content: "";
    position: absolute; inset: 0;
    pointer-events: none;
    background: rgba(216, 255, 84, .16);
    animation: companion-art-glow var(--cd-cycle) ease-in-out infinite;
}

@keyframes companion-art-breathe {
    0%, 100% { transform: translateY(0) scale(1, 1); }
    50% { transform: translateY(-.8%) scale(.996, 1.012); }
}
/* Two bounces per stride (one flight phase per foot), a touch of squash on each footfall, a lean that alternates. */
@keyframes companion-art-run {
    0%   { transform: translateY(0) scale(1.014, .986) rotate(0deg);        animation-timing-function: cubic-bezier(.2, .6, .35, 1); }
    25%  { transform: translateY(-3.4%) scale(.992, 1.012) rotate(1deg);    animation-timing-function: cubic-bezier(.65, 0, .8, .4); }
    50%  { transform: translateY(0) scale(1.014, .986) rotate(0deg);        animation-timing-function: cubic-bezier(.2, .6, .35, 1); }
    75%  { transform: translateY(-3.4%) scale(.992, 1.012) rotate(-1deg);   animation-timing-function: cubic-bezier(.65, 0, .8, .4); }
    100% { transform: translateY(0) scale(1.014, .986) rotate(0deg); }
}
@keyframes companion-art-hop {
    0%   { transform: translateY(0) scale(1.03, .96);      animation-timing-function: cubic-bezier(.2, .6, .35, 1); }
    50%  { transform: translateY(-6%) scale(.985, 1.035);  animation-timing-function: cubic-bezier(.65, 0, .8, .4); }
    100% { transform: translateY(0) scale(1.03, .96); }
}
@keyframes companion-art-glow { 0%, 100% { opacity: 0; } 50% { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
    .companion-art, .companion-art-frame::after { animation: none !important; }
}
