/* The customize view and the Name Tag tutorial that points through it. */

/* ---------------------------------------------------------------------------
   Customize view
   The ninja's name, the one slot and the Skill tree, in the same portrait area the menu uses and reached
   from it through the same curtain, set below the floating top bar. The tree is laid
   out from the config: one row per tier, the nodes of a row spread evenly across it, and the wires drawn
   behind them from the same coordinates.
   --------------------------------------------------------------------------- */
.customize-view {
    position: relative;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: calc(2.75rem + env(safe-area-inset-top)) 16px 16px;
    overflow-x: hidden;
    overflow-y: auto;
    font-family: "Trebuchet MS", system-ui, sans-serif;
    color: #f9efd7;
    background-color: #06142e;
}

/* The menu's shrine, darkened, and a wash that deepens towards the detail card. */
.customize-view::before,
.customize-view::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.customize-view::before {
    z-index: -2;
    background: url("../art/menu-moonlit-shrine.sha256-46b3beb0c2f56140.webp") center / cover;
    filter: brightness(0.48) saturate(0.7);
}

.customize-view::after {
    z-index: -1;
    background: linear-gradient(#06142ed1, #06142edb 35%, #020914f2 100%);
}

.customize-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex: 0 0 auto;
}

.customize-back {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: #061424a8;
    box-shadow: inset 0 0 0 1px #758ba2aa;
    color: inherit;
    cursor: pointer;
    touch-action: manipulation;
}

.customize-back .icon {
    width: 22px;
    height: 22px;
    stroke-width: 2.4;
    vertical-align: middle;
}

.customize-title {
    margin: 0;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: 0.15em;
    text-transform: uppercase;
}

.customize-orbs {
    display: flex;
    align-items: center;
    gap: 5px;
    min-width: 38px;
    justify-content: flex-end;
    color: #ffe3a0;
    font-size: 18px;
    font-weight: 900;
    font-variant-numeric: tabular-nums;
}

.customize-orbs-mark {
    display: block;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, #fffefa, #d0ecf0 40%, #78c1e4a8 80%, transparent);
    box-shadow: 0 0 8px #b9eaffae;
}

/* ---- Identity: the name and the one slot ---- */
.customize-identity {
    display: grid;
    grid-template-columns: 1fr 62px;
    gap: 15px;
    align-items: center;
    flex: 0 0 auto;
    margin: 22px 6px 0;
}

.customize-name-cell {
    min-width: 0;
}

.customize-name {
    display: flex;
    align-items: center;
    gap: 7px;
    height: 33px;
    border-bottom: 1px solid #96a6b1;
}

.customize-name input {
    width: 100%;
    min-width: 0;
    padding: 0;
    border: 0;
    background: transparent;
    color: #fff1d4;
    font: 700 17px "Trebuchet MS", sans-serif;
    letter-spacing: 0.045em;
    outline: none;
}

.customize-name input::placeholder {
    color: #ffe1a880;
    font-weight: 400;
}

.customize-name .icon {
    flex: 0 0 auto;
    color: #ffd18d;
    font-size: 16px;
}

/* Without the Name Tag the field only shows the anonymous name, dimmed. */
.customize-name-locked {
    border-bottom-style: dashed;
    border-bottom-color: #56697b;
}

.customize-name-locked input {
    color: #8193a3;
    cursor: default;
}

.customize-name-locked .icon {
    color: #56697b;
}

/* A Name Tag owner with no name yet: the field is what stands between them and the board, and its underline
   alone says so. The tutorial's hand points at it, and nothing is written under it. */
.customize-name-needed {
    border-bottom: 2px solid #e58e4d;
}

.customize-name-invalid {
    border-bottom: 2px solid #e0674d;
}

.customize-name-note {
    margin: 5px 0 0;
    font-size: 12px;
    line-height: 1.3;
    color: #a7bad0;
}

.customize-name-note-error {
    color: #ff9c86;
}

/* The one slot. It keeps its frame while empty and simply holds nothing. */
.customize-equipped {
    position: relative;
    width: 62px;
    height: 62px;
    border: 0;
    border-radius: 11px;
    color: #ffdc9e;
    background: #26364a;
    box-shadow: inset 0 0 0 2px #f5cb81;
}

/* The icons share one cell, so the outgoing and incoming icons of a change sit exactly on each other. */
.customize-equipped-swap {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
}

.customize-equipped-swap > .icon {
    grid-area: 1 / 1;
    width: 39px;
    height: 39px;
}

/* A change of what is in the slot: a warm glow bursts from its centre, fully bright and covering the icon
   at 31% of --slot-flash-duration, which is when the outgoing icon goes and the incoming one appears
   (CustomizeView.razor SlotSwapMs over SlotFlashMs), then spreads and fades over the new icon. The swap is
   hidden inside the glow rather than cut. */
.customize-equipped-flash {
    position: absolute;
    inset: -10px;
    border-radius: 50%;
    background: radial-gradient(closest-side, #fffaf0 0%, #ffe6b3 45%, #f5b564cc 70%, transparent 100%);
    pointer-events: none;
    opacity: 0;
    animation: slot-flash var(--slot-flash-duration, 420ms) ease-out both;
}

.customize-equipped-outgoing {
    animation: slot-icon-before-swap var(--slot-flash-duration, 420ms) linear both;
}

.customize-equipped-incoming {
    animation: slot-icon-after-swap var(--slot-flash-duration, 420ms) linear both;
}

@keyframes slot-flash {
    0%   { opacity: 0; transform: scale(0.35); }
    31%  { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.45); }
}

@keyframes slot-icon-before-swap {
    0%, 30.9% { opacity: 1; }
    31%, 100% { opacity: 0; }
}

@keyframes slot-icon-after-swap {
    0%, 30.9% { opacity: 0; }
    31%, 100% { opacity: 1; }
}

@keyframes slot-icon-fade-out {
    from { opacity: 1; }
    to   { opacity: 0; }
}

@keyframes slot-icon-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* ---- The tree ----
   The plane is inset so a badge centred on its top edge, and a cost line under a badge centred on its
   bottom edge, both stay inside the tree. Node positions and wire ends are percentages of the plane. */
.skill-tree {
    position: relative;
    flex: 1 1 auto;
    min-height: 250px;
    max-height: 420px;
    margin: 18px 0 14px;
}

.skill-tree-plane {
    position: absolute;
    top: 31px;
    bottom: 50px;
    left: 4px;
    right: 4px;
}

.skill-wires {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.skill-wire {
    fill: none;
    stroke: #6d8da8;
    stroke-width: 2;
    stroke-opacity: 0.8;
}

.skill-wire-future {
    stroke: #526172;
    stroke-opacity: 0.65;
    stroke-dasharray: 4 4;
}

/* A node is centred on its point by its margins rather than by a translate, so the press scale the shell
   gives every button shrinks it in place. */
.skill-node {
    position: absolute;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 64px;
    margin: -28.5px 0 0 -32px;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    text-align: center;
    cursor: pointer;
    touch-action: manipulation;
}

/* The badge's edge is an inset shadow in the state's colour (--badge-edge), with the state's glow outside it
   (--badge-halo), rather than a border: Firefox leaves a seam between a rounded border and the fill inside
   it. Each state sets the two variables and this one rule composes them. */
.skill-badge {
    --badge-edge: #8eaab7;
    --badge-halo: 0 5px 10px #0008;
    display: grid;
    place-items: center;
    width: 57px;
    height: 57px;
    border: 0;
    border-radius: 11px;
    color: #eff6e4;
    background: linear-gradient(#31435a, #13243a);
    box-shadow: inset 0 0 0 2px var(--badge-edge), var(--badge-halo);
}

.skill-badge .icon {
    width: 29px;
    height: 29px;
}

.skill-cost {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.25em;
    margin-top: 5px;
    color: #f5cf87;
    font-size: 12px;
    line-height: 1.15;
    white-space: nowrap;
}

.skill-cost .skill-cost-mark {
    width: 14px;
    height: 14px;
    stroke-width: 2.6;
    vertical-align: -0.2em;
}

/* The Orb dot a price is written after, sized to the figure beside it. */
.customize-view .icon.orb-price-mark {
    flex: 0 0 auto;
    width: 0.8em;
    height: 0.8em;
    stroke: none;
}

.skill-node.owned .skill-badge {
    --badge-edge: #ddbc79;
    background: linear-gradient(#544432, #2c2930);
}

.skill-node.equipped .skill-badge {
    --badge-edge: #ffda81;
    --badge-halo: 0 0 0 3px #c8864d, 0 0 18px #eda35480;
}

.skill-node.available .skill-badge {
    --badge-edge: #d69d65;
}

.skill-node.unaffordable .skill-badge {
    --badge-edge: #7a8290;
    color: #a0acb6;
}

.skill-node.locked .skill-badge {
    --badge-edge: #56697b;
    color: #77899b;
    background: #132032;
}

.skill-node.locked .skill-cost {
    color: #7f94a5;
}

.skill-node.selected .skill-badge {
    --badge-halo: 0 0 0 3px #e58e4d, 0 0 20px #e58e4d99;
}

.skill-tree-empty {
    margin: 2rem 0 0;
    font-size: 0.8125rem;
    text-align: center;
    color: var(--text-muted);
}

/* ---- The detail card ----
   A fixed height, three text lines tall: the card never resizes as the selection moves between a Skill with
   one effect and one with three (CustomizeView.razor MaxEffectLinesWithName gives the name's line up first).
   The icons beside text in and around it sit in flex rows, because the base stylesheet index.html loads
   lays every svg out as a block, which would otherwise put each icon on a line of its own. */
.skill-detail {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 12px;
    height: 99px;
    margin: 0 1px;
    padding: 13px;
    border: 0;
    border-radius: 13px;
    background: #12253bea;
    box-shadow: inset 0 0 0 1px #e1ad6d, 0 7px 25px #0008;
}

.skill-detail-copy {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 12px;
}

.skill-detail-copy > .icon {
    flex: 0 0 auto;
    width: 39px;
    height: 39px;
    color: #ffe0a3;
}

.skill-detail-text {
    min-width: 0;
}

.skill-detail-text strong {
    display: block;
    font-size: 16px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.skill-effects {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 13px;
    line-height: 16px;
}

.skill-effect {
    display: flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
}

.skill-effect .icon {
    flex: 0 0 auto;
    width: 13px;
    height: 13px;
}

.skill-effect-value {
    font-weight: bold;
    font-variant-numeric: tabular-nums;
}

.skill-effect-benefit {
    color: #f5cf87;
}

.skill-effect-penalty {
    color: #ff9c86;
}

/* The Skill's name heads the card, over its effect lines. */
.skill-detail-name {
    display: block;
    margin-bottom: 2px;
    font-size: 14px;
    line-height: 16px;
    font-weight: 700;
    color: #f9efd7;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.skill-detail-note {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: #a7bad0;
}

.skill-action {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.3em;
    min-width: 74px;
    height: 44px;
    padding: 0 10px;
    border: 0;
    border-radius: 9px;
    background: #b45d3a;
    box-shadow: inset 0 0 0 1px #ffe0a3;
    color: #fff2cf;
    font-size: 15px;
    font-weight: 900;
    white-space: nowrap;
    cursor: pointer;
    touch-action: manipulation;
}

.skill-action:disabled {
    background: #425166;
    color: #c6d1d6;
    box-shadow: inset 0 0 0 1px #728394;
    cursor: default;
    opacity: 1;
}

.skill-action .icon {
    flex: 0 0 auto;
    stroke-width: 2.4;
}

.skill-action .skill-action-equip {
    width: 27px;
    height: 18px;
}

.skill-action .skill-action-equipped {
    width: 20px;
    height: 20px;
}

.skill-action .skill-action-locked {
    width: 18px;
    height: 18px;
}

/* Nothing on this screen moves beyond the curtain that brought it in, except that a change of the slot
   still is not a cut: its icons cross-fade instead of swapping inside the burst. */
@media (prefers-reduced-motion: reduce) {
    .customize-view button {
        transition: none;
    }

    .customize-view button:active:not(:disabled) {
        transform: none;
    }

    .customize-equipped-flash {
        display: none;
    }

    .customize-equipped-outgoing {
        animation: slot-icon-fade-out 150ms linear both;
    }

    .customize-equipped-incoming {
        animation: slot-icon-fade-in 150ms linear both;
    }
}

/* ---------------------------------------------------------------------------
   Name Tag tutorial
   A wordless pointing hand (Components/TutorialPointer.razor) at the one control the player must press
   next, from their first affordable Orbs to a name on the board, while the controls around it are shut.
   The hand's fingertip is its anchor: each placement puts the tip on a point, turns the hand about it by
   --pointer-angle (0 points straight up) and backs it off along its own axis by --pointer-gap. The glyph
   bobs along the direction it points. It never takes a press.
   --------------------------------------------------------------------------- */
.tutorial-pointer {
    --pointer-angle: 0deg;
    --pointer-gap: 4px;
    position: absolute;
    z-index: 3;
    width: 44px;
    height: 44px;
    margin: -5.5px 0 0 -22px;
    color: #ffe1a8;
    filter: drop-shadow(0 0 6px #eda764c0) drop-shadow(0 3px 4px #000c);
    pointer-events: none;
    transform-origin: 22px 5.5px;
    transform: rotate(var(--pointer-angle)) translateY(var(--pointer-gap));
}

.tutorial-pointer > .icon {
    display: block;
    width: 44px;
    height: 44px;
    stroke-width: 1.8;
    vertical-align: top;
    animation: tutorial-pointer-bob 700ms ease-in-out infinite alternate;
}

@keyframes tutorial-pointer-bob {
    from { transform: translateY(0); }
    to   { transform: translateY(-7px); }
}

/* At the medallion's lower right, aimed up at the yin-yang's centre (Components/Menu/Medallion.razor .yin-yang:
   --yin-yang-size at 50, 41 on the medallion's 270 x 310 box, which the hand is laid out on and scales with). */
.tutorial-pointer-medallion {
    --pointer-angle: -30deg;
    --pointer-gap: 96px;
    left: 133px;
    top: 124px;
}

/* By the Name Tag's node, from its lower right, aimed at the centre of its badge. The node's point is
   inline (CustomizeView.razor), as the node's own is. */
.tutorial-pointer-tree-node {
    --pointer-angle: -45deg;
    --pointer-gap: 30px;
}

/* Left of the Unlock button, level with it, aimed right at it. */
.tutorial-pointer-action {
    --pointer-angle: 90deg;
    --pointer-gap: 6px;
    left: 0;
    top: 50%;
}

/* Above the name field's right end, aimed down at it, in the gap between the field and the header. */
.tutorial-pointer-name {
    --pointer-angle: 180deg;
    --pointer-gap: 2px;
    left: calc(100% - 44px);
    top: 4px;
}

/* An element the hand is laid out inside. */
.tutorial-host {
    position: relative;
}

/* The medallion while it is the only way forward: a soft gold halo breathes round the yin-yang. */
.loadout-shrine.tutorial-target::after {
    content: "";
    position: absolute;
    top: 41px;
    left: 50px;
    width: var(--yin-yang-size);
    height: var(--yin-yang-size);
    border-radius: 50%;
    pointer-events: none;
    animation: tutorial-halo 1400ms ease-in-out infinite alternate;
}

@keyframes tutorial-halo {
    from { box-shadow: 0 0 10px #ffe1a833; }
    to   { box-shadow: 0 0 30px #ffd083a0; }
}

/* Controls the tutorial shuts. They stay where they are, dimmed, and say nothing about why. */
.customize-back:disabled {
    cursor: default;
    opacity: 0.45;
}

.skill-node:disabled {
    cursor: default;
    opacity: 0.55;
}

@media (prefers-reduced-motion: reduce) {
    .tutorial-pointer > .icon {
        animation: none;
    }

    .loadout-shrine.tutorial-target::after {
        animation: none;
        box-shadow: 0 0 22px #ffd08370;
    }
}
