/* ── Enhancement top nav ──────────────────────────────────── */
/* The six section tabs, each opening its own trees — see the flyouts below. Bleeds to the page edge
   the same way .class-top-nav does, cancelling out body's 20px side padding, rather than sitting
   indented under it like the rest of the page. */

.enh-top-nav {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 10px;
    background: #141414;
    border-bottom: 1px solid #333;
    margin: 0 -20px 20px;
    padding: 6px 16px;
}

.enh-top-nav-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
}

.enh-top-nav-tabs a {
    font-size: 0.82rem;
    padding: 4px 10px;
    color: #888;
    text-decoration: none;
    border-radius: 3px;
    white-space: nowrap;
}
.enh-top-nav-tabs a:hover { color: #ccc; background: #1e1e1e; }
.enh-top-nav-tabs a.active { color: #c8a84b; background: #261f00; }

/* ── Section flyouts ──────────────────────────────────────── */
/* Each section tab opens its own trees on hover, so any tree is reachable from any page without
   returning to an index first. Class needs two levels — 59 trees in one list would run past the
   bottom of the window, where 15 classes each opening their own three to six does not.
   Hover and keyboard focus, no script: :focus-within is what opens a level for a keyboard, and
   display:none on the closed levels keeps their links out of the tab order until then. */

/* The bar must not clip a menu that hangs below it. */
.enh-top-nav { overflow: visible; }

.enh-nav-tab { position: relative; }
.enh-nav-tab > a { display: block; }

/* Flush against the trigger, with no decorative gap between them. A gap of even a pixel is dead
   ground the pointer crosses on its way down, and crossing it drops :hover on the trigger and shuts
   the menu — slowly enough and it closes every time, quickly enough and the pointer skips over the
   gap between two frames and it survives. The menu has to stay inside the element it hangs from. */
.enh-nav-drop {
    display: none;
    position: absolute;
    left: 0;
    top: 100%;
    min-width: 190px;
    background: #1C181B;
    border: 1px solid #3B3038;
    border-radius: 3px;
    padding: 4px 0;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.55);
    z-index: 60;
}
.enh-nav-tab:hover > .enh-nav-drop,
.enh-nav-tab:focus-within > .enh-nav-drop { display: block; }

/* Only the menus that hold nothing nested may scroll. Setting overflow-y on the Class menu would
   compute overflow-x to auto along with it — the pair cannot be visible on one axis and clipped on
   the other — and that clips off the submenu opening beside it, which is how this was found: the
   DOM reported the submenu open while nothing was drawn. Racial's 19 is the longest flat menu. */
.enh-nav-drop-flat {
    max-height: 78vh;
    overflow-y: auto;
}

.enh-nav-drop > a {
    display: block;
    padding: 3px 11px;
    font-size: 0.78rem;
    color: #c8a84b;
    text-decoration: none;
    white-space: nowrap;
    border-radius: 0;
}
.enh-nav-drop > a:hover { background: #261f00; color: #e0bb60; }
.enh-nav-drop > a.current { color: #fff; font-weight: bold; }

/* Second level: the classes inside the Class menu, each opening its own trees beside itself. */
.enh-nav-sub { position: relative; }
.enh-nav-sub:hover,
.enh-nav-sub:focus-within { background: #261f00; }

.enh-nav-sub-trigger {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 11px;
    font-size: 0.78rem;
    color: var(--text-dim);
    white-space: nowrap;
}
.enh-nav-sub-trigger img { width: 15px; height: 15px; flex-shrink: 0; }
/* The arrow says the row opens further rather than going somewhere itself. */
.enh-nav-sub-trigger::after {
    content: '›';
    margin-left: auto;
    padding-left: 10px;
    color: var(--text-faint);
}
.enh-nav-sub:hover .enh-nav-sub-trigger,
.enh-nav-sub:focus-within .enh-nav-sub-trigger { color: var(--text); }

/* Opens beside its parent, overlapping by a pixel so crossing the gap never closes it. */
.enh-nav-drop-sub {
    left: calc(100% - 1px);
    top: -5px;
    max-height: none;
}
.enh-nav-sub:hover > .enh-nav-drop-sub,
.enh-nav-sub:focus-within > .enh-nav-drop-sub { display: block; }

.enh-nav-tab:focus-visible,
.enh-nav-sub:focus-visible {
    outline: 1px solid #c8a84b;
    outline-offset: 1px;
}

/* ── Peer band ────────────────────────────────────────────── */
/* Under the tabs on a tree's own page: every tree of that tree's section, reachable in a hover and
   a click. The classes are a single row of names and each opens its trees on hover, because the
   alternative — all 65 names inline — cost 228px of the page before the panel even began. Nothing
   here needs script: :hover opens the menu for a mouse and :focus-within opens it for a keyboard.
   Bleeds to the page edge the same way .enh-top-nav does, cancelling out body's 20px side padding. */

.enh-peer {
    position: relative;
    /* Above the page below it, so an open menu is not painted over by the tree panel. */
    z-index: 5;
    background: #161314;
    border-bottom: 1px solid #2a252a;
    margin: -20px -20px 20px;
    padding: 7px 16px 8px;
}

/* The fifteen classes, as cards — the same band every other section's page carries, rather than the
   row of 0.72rem names this used to be. Packed against a smaller minimum than the tree bands take:
   these hold "Favored Soul" at longest, where those hold "Aasimar: Scourge of the Dead". */
.enh-peer-bar {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
    gap: 6px;
}

/* Stays the positioned container the flyout hangs off. A class has no page of its own, so unlike a
   tree card this one opens its trees rather than leading anywhere. */
.enh-peer-menu { position: relative; }

.enh-peer-trigger {
    position: relative;
    display: block;
    height: 48px;
    border: 1px solid var(--line);
    border-radius: 4px;
    overflow: hidden;
    cursor: pointer;
}
.enh-peer-menu:hover .enh-peer-trigger,
.enh-peer-menu:focus-within .enh-peer-trigger { border-color: #555; }
.enh-peer-menu.current .enh-peer-trigger { border-color: var(--gold); }

.enh-peer-plate {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* 53%, as the shrunk tree cards take — halving a card's height keeps the top of the crop unless
       the window is moved down, and the top of a class plate is its pale bloom. */
    object-position: center 53%;
}

.enh-peer-face {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 12px 8px 4px;
    font-size: 0.68rem;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #fff;
    text-shadow: 0 1px 3px #000, 0 0 9px #000;
    background: linear-gradient(to top, rgba(6, 5, 6, 0.92), rgba(6, 5, 6, 0));
    white-space: nowrap;
}
.enh-peer-face img {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    filter: drop-shadow(0 1px 3px #000);
}
.enh-peer-menu:hover .enh-peer-face,
.enh-peer-menu:focus-within .enh-peer-face,
.enh-peer-menu.current .enh-peer-face { color: var(--gold-lit); }

/* display:none rather than opacity, so the closed menus are not in the tab order and a screen
   reader does not read fifteen classes' worth of links before the page starts. */
/* Flush, for the same reason .enh-nav-drop is: a gap between a trigger and the menu it opens is
   dead ground that drops :hover on the way across. */
.enh-peer-drop {
    display: none;
    position: absolute;
    left: 0;
    top: 100%;
    min-width: 186px;
    background: #1C181B;
    border: 1px solid #3B3038;
    border-radius: 3px;
    padding: 4px 0;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.55);
    z-index: 30;
}
.enh-peer-menu:hover .enh-peer-drop,
.enh-peer-menu:focus-within .enh-peer-drop { display: block; }

.enh-peer-drop a {
    display: block;
    padding: 3px 11px;
    font-size: 0.78rem;
    color: #c8a84b;
    text-decoration: none;
    white-space: nowrap;
}
.enh-peer-drop a:hover { background: #261f00; color: #e0bb60; }
.enh-peer-drop a.current { color: #fff; font-weight: bold; }

.enh-peer-bar +
.enh-peer-menu:focus-visible,
.enh-peer a:focus-visible {
    outline: 1px solid #c8a84b;
    outline-offset: 1px;
}

/* ── Destiny spheres ──────────────────────────────────────── */
/* Four panels, each headed by the plate art its own destinies share. Used twice: as the whole of the
   /EpicDestiny index, and as the header band on a destiny's own page — the same partial and the
   same styles, so the two cannot drift apart. */

.destiny-spheres {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    /* Stretch, not start. Arcane holds four destinies and the other three hold three apiece, so
       letting each panel stop at its own last name left one panel a line taller than its
       neighbours — which reads as a mistake rather than as a difference in content. */
    align-items: stretch;
    gap: 8px;
}

.destiny-sphere {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 4px;
    overflow: hidden;
}

/* The plate fills the panel rather than a band across the top of it. A 299x466 portrait against a
   panel roughly twice as wide as it is tall, so object-fit carries the crop instead of squashing it.

   20%, and it wants to stay high. These four are painted plates with their subject in the top
   third — the dragon's head and wing, the angel's wings, the flail and its chain, the tree's
   canopy — over a dark lower half carrying nothing. That is the opposite of the class and tree
   plates, which are abstract washes blooming at the top and take 45% to get past it; the same
   number here drops Arcane below its dragon and leaves a red blob. Checked all four together at
   0/10/20/28/45 — 20 is the only one where every sphere shows its subject, and below it Divine and
   Primal blow out into their own light source.

   Note the box is the whole panel now rather than the old 66px band, so these percentages do not
   mean what they did before that change. */
.destiny-sphere-plate {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 20%;
}

/* No longer holds the art — it is the clear window above the name, where the plate is shown
   untouched. Everything below this is veiled. */
.destiny-sphere-art {
    position: relative;
    z-index: 1;
    height: 66px;
    flex-shrink: 0;
}

.destiny-sphere-name {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 14px 10px 5px;
    font-size: 0.72rem;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 0.13em;
    color: #fff;
    text-shadow: 0 1px 3px #000, 0 0 9px #000;
    background: linear-gradient(to top, rgba(6, 5, 6, 0.92), rgba(6, 5, 6, 0));
}

/* The veil. It picks up where the name's own gradient leaves off — full strength directly under the
   label, easing as it falls so the lower half of the plate stays visible through it. It stops
   easing at 0.72: gold on a lit part of a plate is legible down to about there and not below it.
   flex: 1 makes it cover the slack a stretched panel gains, so a three-destiny panel is veiled to
   the same edge as Arcane's four rather than showing bare plate under its last name. */
.destiny-sphere-list {
    position: relative;
    z-index: 1;
    flex: 1;
    padding: 5px 10px 7px;
    background: linear-gradient(to bottom,
        rgba(6, 5, 6, 0.92) 0,
        rgba(6, 5, 6, 0.84) 45%,
        rgba(6, 5, 6, 0.72) 100%);
}

.destiny-sphere-list a {
    display: block;
    width: fit-content;
    font-size: 0.82rem;
    line-height: 1.6;
    color: #c8a84b;
    text-decoration: none;
}
.destiny-sphere-list a:hover { color: #e0bb60; text-decoration: underline; }
.destiny-sphere-list a.current { color: #fff; font-weight: bold; }
.destiny-sphere-list a:focus-visible {
    outline: 1px solid #c8a84b;
    outline-offset: 2px;
    border-radius: 2px;
}

/* As a header band the panels sit in the same bleeding strip the other peer content does. */
.enh-peer .destiny-spheres { gap: 6px; }
.enh-peer .destiny-sphere-art { height: 54px; }
.enh-peer .destiny-sphere-list { padding: 4px 9px 5px; }
.enh-peer .destiny-sphere-list a { font-size: 0.78rem; line-height: 1.5; }

/* ── Enhancement / Epic Destiny index ────────────────────── */
/* /Enhancement draws every section as cards — a card per class in Class, a card per tree in the
   other four; /EpicDestiny uses the sphere panels further down. Both share the page title and
   section headings here. */

.enhancement-index-title { font-size: 1.25rem; color: #e0c97a; margin: 9px 0; }

.enhancement-section + .enhancement-section { margin-top: 26px; }

/* Named at a size that carries a run of cards under it. At 0.7rem this was a caption on a grid; the
   grids are now the whole page, five sections deep, and the heading is the only thing telling a
   reader which one they have scrolled into. It keeps the small-caps and the gold, which is how a
   section is marked everywhere else on the site — it is the scale that was wrong, not the style. */
.enhancement-section-heading {
    font-size: 1.05rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: #c8a84b;
    border-bottom: 1px solid var(--line);
    padding-bottom: 6px;
    margin: 0 0 10px;
}

/* ── Class plates ────────────────────────────────────────── */
/* The Class section, headed the way /EpicDestiny heads its spheres: the art each group already
   shares, cropped to a band, with the name over a gradient dark enough to hold white on any of the
   fifteen. See .destiny-sphere, which this is a deliberate echo of.

   This replaced a 170px eight-column tile grid whose whole argument was height — pack the classes
   tight enough and 15 of them land in two rows instead of three. Five columns and a 66px band cost
   about half as much again in height, which is the price of the art and was chosen knowing it.

   Five is stated, not flowed. auto-fill would fit six or seven on a wide screen and strand the
   remainder, and the plate is wide enough at five that a tree name never has to wrap; the
   breakpoints below step down rather than letting the tracks shrink under the longest name
   ("Knight of the Chalice", about 153px). Rows size to their own tallest card, so a row holding
   nothing longer than Bard's four does not pay for Sorcerer's six the way the old grid did. */
.enh-plate-grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 8px;
}

@media (max-width: 1000px) { .enh-plate-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .enh-plate-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 420px)  { .enh-plate-grid { grid-template-columns: 1fr; } }

.enh-plate {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 4px;
    /* The art runs to the card's edge, so the corners have to clip it. */
    overflow: hidden;
}

/* The plate fills the card rather than a band across the top of it, as a destiny sphere's does.

   Cropped at 45%, not the spheres' 20%. The two plate families want opposite windows: a sphere is a
   painted scene with its subject high in the frame, where a class plate is an abstract wash with
   its brightest bloom at the top, so taking the top of one finds its subject and the top of the
   other finds the palest part of the picture. 45% picks up the tinted body, which is the only thing
   that tells one class from another. */
.enh-plate-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 45%;
}

/* No longer holds the art — it is the clear window above the name, where the plate shows untouched.
   Everything below it is veiled. */
.enh-plate-art {
    position: relative;
    z-index: 1;
    height: 66px;
    flex-shrink: 0;
}

.enh-plate-name {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 0;
    padding: 14px 10px 5px;
    font-size: 0.72rem;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 0.13em;
    color: #fff;
    text-shadow: 0 1px 3px #000, 0 0 9px #000;
    background: linear-gradient(to top, rgba(6, 5, 6, 0.92), rgba(6, 5, 6, 0));
}

/* The class icon keeps its place from the old tile header. It needs its own shadow: the name has a
   text-shadow to lift it off the art and the icon would otherwise be the one flat thing on it. */
.enh-plate-name > img {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    filter: drop-shadow(0 1px 2px #000);
}

/* The veil, picking up where the name's own gradient leaves off: full strength directly under the
   label, easing as it falls so the lower part of the plate stays visible through it. It stops at
   0.72 — gold on a lit part of a plate is legible down to about there and not below. flex: 1 makes
   it cover the slack a card gains from being in a row with a taller one, so Bard's four trees are
   veiled to the same edge as Sorcerer's six rather than showing bare plate under the last name. */
.enh-plate-list {
    position: relative;
    z-index: 1;
    flex: 1;
    list-style: none;
    margin: 0;
    padding: 5px 10px 8px;
    background: linear-gradient(to bottom,
        rgba(6, 5, 6, 0.92) 0,
        rgba(6, 5, 6, 0.84) 45%,
        rgba(6, 5, 6, 0.72) 100%);
}

/* The hit area is the name, not the column it sits in. A block anchor stretched the full width of
   the card, so the hover underline ran out past the end of the word and a click landed on empty
   space well to the right of anything readable. fit-content sizes the box to the text while
   leaving it a block, so the line spacing is exactly what it was. */
.enh-plate-list a {
    display: block;
    width: fit-content;
    font-size: 0.8rem;
    line-height: 1.55;
    color: #c8a84b;
    text-decoration: none;
}
.enh-plate-list a:hover { color: #e0bb60; text-decoration: underline; }
.enh-plate-list a:focus-visible {
    outline: 1px solid #c8a84b;
    outline-offset: 2px;
    border-radius: 2px;
}

/* ── Tree cards ──────────────────────────────────────────── */
/* One card per tree, for the four sections the client does not split into groups: Universal,
   Racial, Iconic and Reaper. Used on /Enhancement/{Section} and again, shrunk, as the band on an
   individual tree's page. Column count and band height come in from the partial, which sizes them
   to how many trees the section holds.

   Wider cards give the band the height to be a picture rather than a strip — a 66px band under a
   480px card reads as a rule, not as art. */
/* auto-fill against a fixed minimum, so a card is the same size on Reaper's page as on Racial's and
   a fuller section takes more rows rather than smaller cards. 300px holds the longest name any of
   the four carries — "Vistani Knife Fighter" — beside a 32px icon without wrapping. */
.enh-tree-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    --card-band: 112px;
    gap: 8px;
}

.enh-tree-card {
    display: block;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 4px;
    overflow: hidden;
    text-decoration: none;
}
.enh-tree-card:hover { border-color: #555; text-decoration: none; }
.enh-tree-card:focus-visible { outline: 2px solid #c8a84b; outline-offset: 2px; }

/* The tree being read, when the band is on a tree's own page. */
.enh-tree-card.current { border-color: var(--gold); }

.enh-tree-card-art {
    position: relative;
    height: var(--card-band, 130px);
}
.enh-tree-card-plate {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* 45%, as the class plates take — these washes bloom at the top too, and cropping there returns
       the palest part of them. */
    object-position: center 45%;
}

.enh-tree-card-name {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 18px 10px 7px;
    font-size: 0.78rem;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: #fff;
    text-shadow: 0 1px 3px #000, 0 0 9px #000;
    background: linear-gradient(to top, rgba(6, 5, 6, 0.92), rgba(6, 5, 6, 0));
}
.enh-tree-card:hover .enh-tree-card-name,
.enh-tree-card.current .enh-tree-card-name { color: var(--gold-lit); }

/* Drawn far larger than a class card's 20px, because in these sections it is often the only picture
   that differs — and in Reaper it does not differ at all. The name beside it finishes the job. */
.enh-tree-card-icon {
    width: var(--card-icon, 32px);
    height: var(--card-icon, 32px);
    flex-shrink: 0;
    border-radius: 3px;
    filter: drop-shadow(0 1px 3px #000);
}

/* On the overview, where a tree card sits a section away from a class card, the two have to be the
   same width or the page reads as unrelated grids stacked up rather than as one taxonomy. So the
   tree grid takes the plate grid's five stated columns and its breakpoints here, and keeps its own
   auto-fill packing on a section's landing page, where there is nothing beside it to match.

   The band shortens to the plate's 66px for the same reason: side by side, a 112px picture over
   five Universal cards next to a 66px one over fifteen class cards is the same component drawn at
   two sizes. */
.enh-overview .enh-tree-grid {
    grid-template-columns: repeat(5, minmax(0, 1fr));
    --card-band: 66px;
    --card-icon: 26px;
}

@media (max-width: 1000px) { .enh-overview .enh-tree-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .enh-overview .enh-tree-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 420px)  { .enh-overview .enh-tree-grid { grid-template-columns: 1fr; } }

/* Same crop as the band on a tree's page, and for the same reason: shortening the box from 112px
   would hold the top of the plate and throw away the bottom, returning the pale bloom these washes
   carry at their top edge. */
.enh-overview .enh-tree-card-plate { object-position: center 53%; }

.enh-overview .enh-tree-card-name {
    padding: 14px 9px 6px;
    font-size: 0.74rem;
    letter-spacing: 0.08em;
    gap: 7px;
}

/* As a band on a tree's own page. Packed against a minimum rather than given a column count: the
   four sections run from 3 trees to 19, and one count that suited Reaper would put Racial on a
   single unreadable row. The minimum is what holds the longest name in any of them — "Aasimar:
   Scourge of the Dead" — on one line.

   Half the height a card takes on a landing page. Racial is what forces it: nineteen cards is four
   rows however they are packed, and at full height that is four hundred pixels of header standing
   between the tabs and the tree the page is about. The other three sections take the same size —
   it is one band, and a Reaper page and a Racial page should not disagree about how tall it is. */
.enh-tree-grid--band {
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    --card-band: 48px;
    --card-icon: 24px;
    gap: 6px;
}

/* Halving the box would otherwise keep the top of the crop and throw away the bottom. Moving the
   window down instead holds the lower edge roughly where it was, so the band loses the pale bloom
   at the top of the plate rather than the tinted part underneath it. */
.enh-tree-grid--band .enh-tree-card-plate { object-position: center 53%; }

.enh-tree-grid--band .enh-tree-card-name {
    padding: 12px 8px 4px;
    font-size: 0.68rem;
    letter-spacing: 0.06em;
    gap: 6px;
}

/* ── Section landing pages ───────────────────────────────── */
/* /Enhancement/{Section}: one section on its own, drawn by the same partials the overview uses.
   Nothing to size here — a grouped section is the plate grid and a flat one is the tree grid, both
   of which lay themselves out. */

.enh-category-empty { color: var(--text-faint); font-style: italic; font-size: 0.88rem; }

/* ── Detail page header ───────────────────────────────────── */

.enhancement-detail-page { display: flex; flex-direction: column; gap: 20px; }

/* Jumped-to headings otherwise land hard against the top of the viewport. */
#tree, .enh-tier-table { scroll-margin-top: 16px; }


.enhancement-detail-header { display: flex; align-items: center; gap: 14px; }

.enhancement-detail-icon { width: 64px; height: 64px; flex-shrink: 0; }

.enhancement-detail-section {
    font-size: 0.78rem;
    color: #999;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.enhancement-detail-title { margin: 2px 0 0; font-size: 1.5rem; color: #e0c97a; }

/* ── Tree panel ───────────────────────────────────────────── */
/* The in-game panel rebuilt as two CSS grids: a five-column tier grid with tier 1 at the bottom
   (the client draws it that way, so this does too), and a six-cell core strip below it. Every
   prereq edge in the game is axis-aligned — straight up a column or straight across a row, never
   both at once — so arrows are plain grid items (a gradient shaft plus a real arrowhead sprite)
   rather than an SVG overlay; see EnhancementViewModelBuilder for where that shape is verified.
   Every image this file draws — cell container, icon border, core strip, arrowheads — is one of
   the fixed EnhancementChromeImages ids, resolved to a URL once per panel and handed down as the
   custom properties _EnhancementTreePanel.cshtml sets on .enh-panel; nothing here names a CDN path
   itself. */

.enh-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    /* Both tight, because the height is fixed and a 5-tier tree very nearly fills it: five 57px rows
       plus their 8px gaps is 317 of the 324 left once the core strip, its label and the footer have
       taken theirs. Anything more generous here and the footer is pushed out through the bottom. */
    gap: 5px;
    padding: 4px 0;
    border: 1px solid #333;
    border-radius: 6px;
    background-color: #0c0c0c;
    /* The client's own cell art is 47x57, not square — the extra 10px of height below the 36x36
       icon is where the rank counter sits (see .enh-cell-icon-area / .enh-cell-rank below). */
    --enh-cell-w: 47px;
    --enh-cell-h: 57px;
    /* Every one of the 112 tree backgrounds is the same 299x466 portrait, so that art — not the
       contents — is what the panel measures. The box is pinned to it exactly (border-box, so the
       299x466 is the padding box the background is positioned against, with the 1px border added
       outside), and the art is drawn at its own size rather than "cover": no crop, no scale, on
       every tree.
       Sizing from the contents instead is what this replaced, and it could not hold the art still.
       A tree has either 4 tier rows (18 racial and all 12 iconic) or 5 (the other 82), never the
       4-6 an earlier note here guessed at, and those two row counts produced two different panel
       heights — 504px and 439px against art that is 466. "cover" then had to crop 22px off the
       width of every 5-tier tree and 30px off the height of every 4-tier one. Fixing the height
       and letting .enh-grid absorb the difference is what lets one plate serve both, which is
       exactly what the client does with it. */
    box-sizing: border-box;
    width: 301px;
    height: 468px;
    /* auto, not cover or 100% — the art is drawn at its own intrinsic size, so if one ever ships at
       a size other than 299x466 it shows up as a gap rather than being silently rescaled to hide it. */
    background-repeat: no-repeat;
    background-position: center;
    background-size: auto;
    margin: 0 auto;
}

.enh-grid, .enh-cores {
    display: grid;
    justify-content: center;
}

.enh-grid {
    grid-template-columns: repeat(var(--enh-cols), var(--enh-cell-w));
    grid-template-rows: repeat(var(--enh-rows), var(--enh-cell-h));
    /* No flex growth and no distribution: the lattice is a fixed five rows of 57px on every tree
       (see panelRows in _EnhancementTreePanel.cshtml), so the grid is the same 317px tall whether
       the tree fills all five or only four. A 4-tier tree leaves its top row empty, which is the
       clear band of background the client shows above a racial tree — not something to even out.
       Anchoring it this way is also what keeps a given tier at the same height across every tree. */
    /* 5 columns x 47px = 235px of cells; the 299px-wide background leaves 64px over that to spend
       on gutters. Split it 32/32 between the 4 inter-column gaps (8px each) and the two side
       margins (16px each, folded into this padding rather than the panel's, so .enh-panel's
       fit-content width comes out to exactly 299px with no padding of its own to add back on) —
       that is what actually lands the grid on the art instead of floating inside it. */
    gap: 8px;
    padding: 0 16px;
}

.enh-cores {
    grid-template-columns: repeat(6, var(--enh-cell-w));
    grid-template-rows: var(--enh-cell-h);
    /* No 299px target to hit here — six cells at 47px is already 282px, so a small gap (not the
       grid's 16px pad, which would push this row wider than the background it sits on) is enough;
       justify-content: center takes up whatever is left either side. */
    gap: 3px;
    /* The strip art is a box the cores sit *inside*, not a band cut to their height, so it needs
       clearance above and below them — drawn at its native 62px it hugged the row and read as a
       stripe. Padding opens that clearance and the background is drawn to match. */
    padding: 12px 0 10px;
    /* The real 3-slice strip: a fixed cap at each end and a horizontally tiled middle section, all
       62px tall — a few px taller than the 57px cell row, so it reads as a frame the cells sit
       inside rather than a band cut to their exact height. background-position anchors all three
       layers to the bottom of the padding box, where the cell row actually is, so the 16px divider
       padding above doesn't push the art down with it. */
    background-image: var(--enh-core-left), var(--enh-core-mid), var(--enh-core-right);
    background-position: left center, center center, right center;
    background-repeat: no-repeat, repeat-x, no-repeat;
    background-size: 13px 100%, auto 100%, 16px 100%;
}

/* The client labels the core strip on the divider above it, half in and half out of the box, so the
   six cores read as their own named group rather than a sixth row that happens to sit lower. */
.enh-cores-label {
    position: relative;
    z-index: 3;
    margin: 0 auto -8px;
    padding: 0 10px;
    width: fit-content;
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: #cfc6ac;
    text-shadow: 0 1px 2px #000;
}

/* Closes the panel the way the client does: the tree's own small icon, then its name, on a dark bar
   across the bottom. */
.enh-panel-footer {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 4px 8px 0;
    padding: 5px 8px;
    background: rgba(0, 0, 0, 0.72);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 3px;
}

.enh-panel-footer-icon {
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    border-radius: 50%;
}

.enh-panel-footer-name {
    font-size: 0.8rem;
    color: #e0c97a;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.enh-cell { position: relative; width: var(--enh-cell-w); height: var(--enh-cell-h); z-index: 2; }
/* position + z-index makes every .enh-cell its own stacking context, so .enh-cell-tip's z-index:60
   only ever wins against its own siblings inside that one cell — it says nothing about how this
   cell's whole subtree compares to a *different* cell's. Every cell shares the same z-index (2), so
   without this rule that comparison is an exact tie, and ties paint in DOM order: a cell later in
   the markup (physically above the hovered one, since tier 1 is at the bottom) paints over it,
   tip included. Giving only the hovered cell a higher z-index breaks the tie in its favour, and its
   whole subtree — icon and tip together — rises above every sibling's regardless of DOM order. */
.enh-cell:hover { z-index: 50; }

/* The cell's own backdrop — the client's plaquette art behind everything else, chosen by IsActive
   rather than by tier or core-ness (see EnhancementCellData.IsActive / EnhancementChromeImages). */
.enh-cell-link {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    height: 100%;
    background-image: var(--enh-container-passive);
    background-size: 100% 100%;
    background-repeat: no-repeat;
    text-decoration: none;
}
.enh-cell--active .enh-cell-link { background-image: var(--enh-container-active); }
.enh-cell-link:hover { filter: brightness(1.25); }

/* The top 47px of the 47x57 cell is the icon's own area — square, matching the cell's width —
   leaving the remaining 10px underneath for .enh-cell-rank, exactly as the client budgets it. */
.enh-cell-icon-area {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: var(--enh-cell-w);
    flex-shrink: 0;
}

/* The border sits on the icon itself, not on the cell's outer edge — it is 39-40px native, a few
   px larger than the 36x36 icon it frames, not the full 47px cell width. */
/* The border is drawn OVER the icon, not behind it, because that is what the client does and it is
   the only way both shapes survive: the icon art is a full square, so a border sitting behind it is
   completely hidden except for the ~2px of clearance around the edge. Clipping the icon to the
   frame's silhouette instead was the previous attempt, and it is wrong — it eats the corners off
   square icons that are supposed to have them. */
.enh-cell-frame {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
}
.enh-cell-frame::after {
    content: '';
    position: absolute;
    inset: 0;
    background-image: var(--enh-border-passive);
    background-size: 100% 100%;
    background-repeat: no-repeat;
    pointer-events: none;
}
.enh-cell--active .enh-cell-frame::after { background-image: var(--enh-border-active); }

.enh-cell-icon { width: 36px; height: 36px; }
/* A 36x36 icon inside a 39-40px frame only has ~2px of clearance — not enough to expose the
   octagon border's corner chamfers, which cut roughly 10px into each corner. Left unclipped, the
   icon's own square corners simply paint over that chamfer and the octagon reads as another square
   (confirmed by screenshot: the active/passive split was invisible until this was added). Passive
   cells need no clip — their frame is already the same square the icon is. */
/* No clip on the icon in either state. The frame overlay above draws the shape; the icon stays the
   square the client ships. */

/* Sits in the 10px the container leaves below the icon. Nudged up a couple of pixels because the
   art's own lower bevel eats into that band — centred on the box, the text reads as overflowing off
   the bottom edge. */
.enh-cell-rank {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    position: relative;
    top: -2px;
    font-size: 0.62rem;
    color: #ccc;
    line-height: 1;
}

/* ── Hover detail ─────────────────────────────────────────── */
/* The same CSS-only visibility toggle as .bt-has-tip / .bt-tip in browse.css, not the fetch-based
   mechanism item-tip.js gives full item panels — this task is explicitly script-free, and a static
   cell (name, cost, ranks, requirement, description all come straight off EnhancementCellData) has
   no need to ask the server for anything. The delay is on showing only, so running the pointer
   across a row does not flicker a tip open for every cell it crosses. */

.enh-cell-tip {
    visibility: hidden;
    position: absolute;
    left: 50%;
    top: calc(100% + 10px);
    transform: translateX(-50%);
    z-index: 60;
    /* box-sizing and min-width together, because the cell this is positioned inside is only 47px
       wide: without them the tip on the core strip collapsed toward its parent's width and wrapped
       into a column three times taller than it was wide. */
    box-sizing: border-box;
    width: 250px;
    min-width: 250px;
    padding: 8px 10px;
    background: #161616;
    border: 1px solid #555;
    border-radius: 4px;
    font-size: 0.78rem;
    line-height: 1.4;
    color: #ccc;
    pointer-events: none;
    transition: visibility 0s linear 0.2s;
}
.enh-cell:hover .enh-cell-tip { visibility: visible; transition-delay: 0.2s; }

/* The core strip is the last thing in the panel, so a tip opening downward from it hangs off the
   bottom past the footer. Those six open upward instead. */
.enh-cores .enh-cell-tip { top: auto; bottom: calc(100% + 10px); }

.enh-cell-tip-name { font-weight: bold; color: #e0c97a; margin-bottom: 4px; }

.enh-cell-tip-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    color: #999;
    font-size: 0.72rem;
    margin-bottom: 4px;
}

.enh-cell-tip-desc { color: #ccc; }

/* ── Prereq arrows ────────────────────────────────────────── */
/* pointer-events is off throughout: an arrow overlapping a cell's corner must never win the hover
   away from the icon underneath it. The shaft stays a plain gradient line — no shaft art was found
   in the client's chrome, only arrowhead sprites — but the head is now the real image instead of a
   CSS border-triangle. Only one asset exists per direction (see EnhancementChromeImages), so unlike
   the container/border pair there is no active/passive or per-cell variation here.
   The sprite itself is a flat mid-gray shape (checked pixel by pixel — R=G=B, no inherent color),
   evidently meant to be tinted at render time rather than shipped pre-colored. Drawn as a mask
   rather than a background-image so it picks up the same solid #c8a84b the shaft gradient ends on,
   instead of sitting on the shaft as a mismatched grey cap. */

.enh-arrow {
    position: relative;
    z-index: 1;
    pointer-events: none;
}

/* The connector is the arrowhead sprite's own stem, continued. All three arrow images carry the
   same one — 4px across, a rgb(97,97,97) edge either side of a 2px rgb(38,38,38) core — sitting
   dead centre of the 24px sprite, so a shaft drawn to that recipe joins the head seamlessly and
   the whole arrow reads as one piece of the client's art.
   What this replaced was a 3px pale cream gradient: both narrower than the stem and the opposite
   tone to it, against arrowheads that are dark grey. Between adjacent tiers the shaft is only the
   8px gutter and sits under the head, so the mismatch stayed hidden; on an arrow that crosses a
   tier the shaft is 73px of bare cream hairline running out of a dark arrowhead, which is where it
   showed up. --enh-arrow-stem-* are the sampled values, named so the two axes cannot drift. */
.enh-panel {
    --enh-arrow-stem-edge: rgb(97, 97, 97);
    --enh-arrow-stem-core: rgb(38, 38, 38);
}
/* The grid item spans from the target cell's row through the source cell's row, so its full height
   covers both cells as well as the gap between them. The connector must only occupy that gap —
   drawing it at 100% ran a line straight through the target cell and out the top of the panel,
   which is what the stray lines off the top row and off the end of the core strip were. Inset by
   one cell at each end: for a one-tier edge that leaves exactly the gutter, and for a two- or
   three-tier edge it correctly runs through the cells in between. */
.enh-arrow-up {
    justify-self: center;
    align-self: start;
    width: 4px;
    height: calc(100% - 2 * var(--enh-cell-h));
    margin-top: var(--enh-cell-h);
    background: linear-gradient(to right,
        var(--enh-arrow-stem-edge) 0 1px,
        var(--enh-arrow-stem-core) 1px 3px,
        var(--enh-arrow-stem-edge) 3px 4px);
}
.enh-arrow-up::after {
    /* The span deliberately includes the target cell's own row, so its box starts at the target's
       far (outer) edge, not at the gap. The head has to move one whole cell length further in to
       land on the target's near edge, in the gap — not its own height, which would only nudge it
       just past that far edge, landing on the cell beyond the target instead. */
    content: '';
    position: absolute;
    top: -4px;
    left: 50%;
    transform: translateX(-50%);
    width: 24px;
    height: 14px;
    background-image: var(--enh-arrow-up);
    background-size: 100% 100%;
    background-repeat: no-repeat;
}

/* Same inset as the vertical connector, on the horizontal axis. */
.enh-arrow-right, .enh-arrow-left {
    align-self: center;
    justify-self: start;
    width: calc(100% - 2 * var(--enh-cell-w));
    margin-left: var(--enh-cell-w);
    height: 4px;
    background: linear-gradient(to bottom,
        var(--enh-arrow-stem-edge) 0 1px,
        var(--enh-arrow-stem-core) 1px 3px,
        var(--enh-arrow-stem-edge) 3px 4px);
}
.enh-arrow-right::after {
    content: '';
    position: absolute;
    right: -4px;
    top: 50%;
    transform: translateY(-50%);
    width: 14px;
    height: 24px;
    background-image: var(--enh-arrow-right);
    background-size: 100% 100%;
    background-repeat: no-repeat;
}
.enh-arrow-left::after {
    content: '';
    position: absolute;
    left: -4px;
    top: 50%;
    transform: translateY(-50%);
    width: 14px;
    height: 24px;
    background-image: var(--enh-arrow-left);
    background-size: 100% 100%;
    background-repeat: no-repeat;
}

/* ── Tier tables ──────────────────────────────────────────── */
/* The panel only surfaces cost/ranks/description on hover; these are the same cells as plain,
   permanent text — one table per tier, in the same order EnhancementScanner sorted the cells into.
   Shape follows .feat-table in browse.css (icon/name/…/description columns, zebra-free hover row)
   since it's the same kind of reference table, just scoped to this page rather than shared. */

.enh-tier-table {
    width: 100%;
    table-layout: fixed;
    /* separate, not collapse: each entry is drawn as its own panel, and collapsed borders share an
       edge between neighbouring rows, so there is nowhere to put a gap between one panel and the
       next. border-spacing supplies that gap. */
    border-collapse: separate;
    border-spacing: 0 6px;
    font-size: 0.84rem;
    margin: 0 0 28px;
}
.enh-tier-table:last-child { margin-bottom: 0; }

.enh-tier-heading {
    caption-side: top;
    text-align: left;
    font-size: 1rem;
    font-weight: 600;
    color: #c8a84b;
    border-bottom: 1px solid #333;
    padding-bottom: 6px;
    margin-bottom: 4px;
}

/* The enhancement side now carries only the icon and the name, the figures having moved to their own
   strip across the foot of each entry, so it needs a fraction of what it did — everything it gives
   up goes to the description. 250px holds the 36px icon plus around 25 characters, which covers 97%
   of the 3169 cell names outright; the longest ("Curative Admixture: Cure and Inflict Serious
   Wounds", at 51) wrap to a second line against an entry that is already 36px tall for the icon. */
.enh-tier-col-enh  { width: 250px; }
.enh-tier-col-desc { width: auto; }

.enh-tier-table th {
    text-align: left;
    color: #888;
    font-weight: 500;
    padding: 4px 8px;
    border-bottom: 1px solid #2a2a2a;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.enh-tier-table td {
    padding: 8px 8px;
    border-bottom: 1px solid #1e1e1e;
    vertical-align: top;
    color: #ccc;
    word-wrap: break-word;
    overflow-wrap: break-word;
}

/* An entry is a panel rather than two rows divided off by a hairline: its content sits on the
   surface and its figures on a darker strip beneath, so where one enhancement ends is a change of
   ground rather than a 1px line to notice. Built from the cells' own borders because a tbody takes
   neither a border nor a radius.

   This is what a rank label and a figure label sharing one flat background could not do on their
   own — both are deliberately gold, so the boundary had to come from the surface instead. */
.enh-tier-entry td {
    background: var(--surface);
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
}
.enh-tier-row-main td { border-bottom: none; padding-bottom: 4px; }
.enh-tier-row-main td:first-child { border-left: 1px solid var(--line); border-top-left-radius: 4px; }
.enh-tier-row-main td:last-child { border-right: 1px solid var(--line); border-top-right-radius: 4px; }

.enh-tier-entry:hover td { background: var(--surface-lift); }
.enh-tier-entry:hover .enh-tier-row-meta td { background: #1B171A; }

/* The gutter between the two columns. 8px of cell padding on each side left the name and the
   description sharing a hairline of whitespace, which read as one run-on block; this pushes them
   apart so the eye can tell where the enhancement ends and its text begins. */
.enh-tier-enh-cell { padding-right: 28px; }

/* The figures close the panel: a darker strip with its own top rule, indented to the description's
   own left edge so they read as belonging to it rather than starting a new column.
   258px = the 250px name column plus the 8px of cell padding the description text starts after,
   measured from the table's own left edge, which is where this full-width cell begins.
   The padding is half what the strip carried as a plain row — sitting on its own ground it no
   longer needs whitespace to hold it apart from the entry below, so that clearance was only
   making the strip tall. */
.enh-tier-row-meta td {
    background: #151214;
    border-top: 1px solid #241F23;
    border-bottom: 1px solid var(--line);
    border-left: 1px solid var(--line);
    border-right: 1px solid var(--line);
    border-radius: 0 0 4px 4px;
    padding: 3px 8px 4px 258px;
}

.enh-tier-headline {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* 36px is what the client's own icon art is — the same size .enh-cell-icon draws in the panel above.
   At 32 these were being resampled down by four pixels, which on art this small softens every edge
   the pixelated hint is here to keep crisp. */
.enh-tier-icon {
    display: block;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    image-rendering: pixelated;
}

.enh-tier-name { font-weight: 500; color: #ddd; }

/* All four figures on one line across the foot of the entry. A grid rather than a plain flex row so
   the tracks stack into columns down the table even though they are no longer table columns, each
   sized to its own longest label-plus-value; with the full width of the table to spend, Prereqs now
   fits on the same line as the rest instead of wrapping to one of its own. */
.enh-tier-meta {
    display: grid;
    grid-template-columns: 130px 90px 150px minmax(0, 1fr);
    align-items: baseline;
    gap: 4px 20px;
    margin: 0;
}

.enh-tier-meta-item {
    display: flex;
    align-items: baseline;
    gap: 4px;
}

/* No longer a row of its own — it is the last track, taking whatever the three fixed ones leave. */
.enh-tier-meta-prereqs {
    min-width: 0;
}

/* The same gold .enh-desc-rank gives its "RANK 1" heading, and the tier caption above the table —
   these labels are the same kind of small uppercase marker, so they take the same colour rather
   than a grey of their own. It also separates label from value, which the previous grey-on-grey
   did only by weight. */
.enh-tier-meta dt {
    color: #c8a84b;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    white-space: nowrap;
}

.enh-tier-meta dd {
    margin: 0;
    color: #ccc;
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
}

.enh-tier-meta-prereqs dd { color: #999; }

.enh-tier-desc { color: #aaa; font-size: 0.8rem; line-height: 1.45; }

/* A selector cell's options, each its own block rather than run together inline. */
.enh-desc-rank {
    color: #c8a84b;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin: 10px 0 2px;
}
.enh-desc-rank:first-child { margin-top: 0; }

/* The option's own icon sits in a gutter to its left, with the name and however many paragraphs of
   description that option carries aligned in the column beside it. Absolutely positioned rather
   than floated or flexed: the description is raw client HTML that can run to three paragraphs
   (Wrack Construct), and nothing wraps it in a container of its own to lay out against. */
.enh-desc-option {
    position: relative;
    margin: 10px 0 0 12px;
    padding-left: 46px;
    min-height: 36px;
}
.enh-desc-option:first-child { margin-top: 0; }

.enh-desc-option-icon {
    position: absolute;
    left: 0;
    top: 0;
    width: 36px;
    height: 36px;
    image-rendering: pixelated;
}

.enh-desc-option-name {
    display: block;
    color: #ddd;
    font-weight: 500;
}
