/*
 * ForeverTome site styles.
 * Tabler supplies the base (Bootstrap + theme); this file only adds what Tabler
 * has no equivalent for: game colour tokens and a few content-site components.
 */

/* ---------------------------------------------------------------- tokens */

:root {
    /* Class colours as published by Blizzard. WoW Forever ships the nine
       original classes; the rest are kept for later game versions. */
    --ft-class-druid: #ff7c0a;
    --ft-class-hunter: #aad372;
    --ft-class-mage: #3fc7eb;
    --ft-class-paladin: #f48cba;
    --ft-class-priest: #ffffff;
    --ft-class-rogue: #fff468;
    --ft-class-shaman: #0070dd;
    --ft-class-warlock: #8788ee;
    --ft-class-warrior: #c69b6d;

    --ft-class-death-knight: #c41e3a;
    --ft-class-demon-hunter: #a330c9;
    --ft-class-evoker: #33937f;
    --ft-class-monk: #00ff98;

    /* Item quality colours. */
    --ft-quality-poor: #9d9d9d;
    --ft-quality-common: #ffffff;
    --ft-quality-uncommon: #1eff00;
    --ft-quality-rare: #0070dd;
    --ft-quality-epic: #a335ee;
    --ft-quality-legendary: #ff8000;
    --ft-quality-artifact: #e6cc80;
    --ft-quality-heirloom: #00ccff;
}

/*
 * Blizzard's class colours are tuned for a dark UI. On the parchment light
 * background (#F0E6D2) the pale ones fall well below a readable contrast ratio,
 * so they get darkened variants in light mode only. Dark mode keeps the canon
 * values untouched.
 */
:root:not([data-bs-theme="dark"]) {
    --ft-class-druid: #b35400;
    --ft-class-hunter: #5f8f2f;
    --ft-class-mage: #1a7f9c;
    --ft-class-paladin: #b9487e;
    --ft-class-priest: #566169;
    --ft-class-rogue: #8a7800;
    --ft-class-warlock: #5d5ec9;
    --ft-class-warrior: #8a6440;
    --ft-class-monk: #00875a;
    --ft-quality-common: #495057;
    --ft-quality-uncommon: #16a34a;
    --ft-quality-artifact: #9a7c2e;
}

/* ------------------------------------------------------- class + quality */

.wow-class,
.wow-quality {
    font-weight: 500;
}

.wow-druid        { --ft-class: var(--ft-class-druid); }
.wow-hunter       { --ft-class: var(--ft-class-hunter); }
.wow-mage         { --ft-class: var(--ft-class-mage); }
.wow-paladin      { --ft-class: var(--ft-class-paladin); }
.wow-priest       { --ft-class: var(--ft-class-priest); }
.wow-rogue        { --ft-class: var(--ft-class-rogue); }
.wow-shaman       { --ft-class: var(--ft-class-shaman); }
.wow-warlock      { --ft-class: var(--ft-class-warlock); }
.wow-warrior      { --ft-class: var(--ft-class-warrior); }
.wow-death-knight { --ft-class: var(--ft-class-death-knight); }
.wow-demon-hunter { --ft-class: var(--ft-class-demon-hunter); }
.wow-evoker       { --ft-class: var(--ft-class-evoker); }
.wow-monk         { --ft-class: var(--ft-class-monk); }

/* The wow-<slug> class only sets the token; this decides how it is used. */
.wow-class        { color: var(--ft-class); }

.wow-q-poor       { color: var(--ft-quality-poor); }
.wow-q-common     { color: var(--ft-quality-common); }
.wow-q-uncommon   { color: var(--ft-quality-uncommon); }
.wow-q-rare       { color: var(--ft-quality-rare); }
.wow-q-epic       { color: var(--ft-quality-epic); }
.wow-q-legendary  { color: var(--ft-quality-legendary); }
.wow-q-artifact   { color: var(--ft-quality-artifact); }
.wow-q-heirloom   { color: var(--ft-quality-heirloom); }

/*
 * Official Blizzard class icons (wwwroot/img/classes). They are square JPEGs with
 * no transparency, so they get their own rounding and a hairline ring rather than
 * sitting flush against the surface.
 */
.ft-class-icon {
    flex: 0 0 auto;
    border-radius: var(--tblr-border-radius);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--ft-class, var(--tblr-border-color)) 55%, transparent);
}

.ft-class-icon-sm {
    border-radius: calc(var(--tblr-border-radius) * .75);
}

/* ----------------------------------------------------------- site chrome */

/* Cinzel is locally hosted under the SIL Open Font License; see fonts/cinzel. */
@font-face {
    font-family: "Cinzel";
    font-style: normal;
    font-weight: 400 900;
    font-display: swap;
    src: url("../fonts/cinzel/cinzel-latin.woff2") format("woff2");
}

/* The emblem, live wordmark and search share a single, deliberate spacing scale. */
.ft-header {
    --tblr-navbar-bg: light-dark(#fbf7ef, #0b242e);
    --tblr-navbar-border-color: light-dark(rgba(47, 112, 104, .2), rgba(98, 165, 165, .24));
    padding-block: .75rem;
}

.ft-header > .container-xl {
    flex-wrap: nowrap;
    gap: clamp(1.25rem, 2.4vw, 2rem);
}

.ft-header-search {
    flex: 1 1 0;
    min-width: 0;
    margin: 0;
}

.ft-header-search .form-control {
    min-height: 3rem;
    border-color: light-dark(rgba(47, 112, 104, .25), rgba(98, 165, 165, .3));
    background-color: light-dark(#fffdf8, #0a1e27);
}

.ft-header-actions {
    flex: 0 0 auto;
    gap: .5rem;
}

.ft-brand {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    gap: .25em;
    font-size: clamp(1.299375rem, 2.464vw, 2.21375rem);
    text-decoration: none;
    border-radius: .25rem;
}

.ft-brand:hover {
    text-decoration: none;
}

.ft-brand:focus-visible {
    outline: 2px solid light-dark(var(--ft-gold-deep), var(--ft-gold));
    outline-offset: 5px;
}

.ft-brand-mark {
    display: block;
    flex: 0 0 auto;
    width: 2.3em;
    height: auto;
}

.ft-brand-copy {
    display: grid;
    gap: .14em;
}

.ft-brand-name {
    display: block;
    color: light-dark(var(--ft-ocean), #f7f0e0);
    font-family: "Cinzel", Georgia, "Times New Roman", serif;
    font-size: 1em;
    font-weight: 700;
    font-feature-settings: normal;
    letter-spacing: -.045em;
    line-height: 1.05;
    text-align: center;
    white-space: nowrap;
}

.ft-brand-accent {
    color: light-dark(var(--ft-gold-deep), #cfad75);
}

.ft-brand-tagline {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .7em;
    color: light-dark(var(--ft-teal-deep), #70aaaa);
    font-size: max(.625rem, .245em);
    font-weight: 600;
    letter-spacing: .12em;
    line-height: 1.25;
    text-transform: uppercase;
    white-space: nowrap;
}

.ft-brand-tagline > span {
    /* Tracking after the final letter should not push the descriptor off-center. */
    margin-inline-end: -.12em;
}

.ft-brand-tagline::before,
.ft-brand-tagline::after {
    content: "";
    flex: 1 1 0;
    height: 1px;
    background: linear-gradient(to right, transparent, currentColor);
    opacity: .8;
}

.ft-brand-tagline::after {
    transform: scaleX(-1);
}

@media (max-width: 767.98px) {
    .ft-header {
        padding-block: .5rem;
    }

    .ft-header > .container-xl {
        justify-content: flex-start;
        gap: .5rem;
    }

    .ft-header-actions {
        display: none;
    }

    .ft-brand {
        font-size: clamp(1.155rem, 5.39vw, 1.63625rem);
    }

    .ft-brand-mark {
        width: 2em;
    }
}

/* Menu bar sits directly under the sticky header and scrolls away with the page. */
.ft-navbar {
    border-bottom: var(--tblr-border-width) solid var(--tblr-border-color);
    background: var(--tblr-bg-surface);
}

.ft-navbar .navbar-collapse > .navbar {
    min-width: 0;
    width: 100%;
}

.ft-navbar .navbar-nav {
    flex-wrap: wrap;
}

.ft-class-menu-heading {
    margin: .25rem .5rem .5rem;
    padding: .75rem;
    border: 1px solid color-mix(in srgb, var(--tblr-link-color) 25%, transparent);
    border-radius: var(--tblr-border-radius);
    background: var(--tblr-bg-surface-secondary);
    color: var(--tblr-heading-color);
    font-size: .8125rem;
    font-weight: 600;
    line-height: 1.5;
    white-space: normal;
}

.ft-hero {
    background:
        radial-gradient(90% 120% at 12% 0%, rgba(var(--tblr-primary-rgb), .16), transparent 62%),
        var(--tblr-bg-surface);
}

/* ------------------------------------------------------------ home page */

.ft-class-tile {
    border-inline-start: 3px solid var(--ft-class, var(--tblr-border-color));
}

.ft-tile-muted {
    opacity: .55;
}

/*
 * Stand-in for an article cover image. Tinted per category so the feed reads as
 * a grid of distinct stories; replace with real <img> covers when they exist.
 */
.ft-thumb {
    height: 7rem;
    border-radius: var(--tblr-border-radius) var(--tblr-border-radius) 0 0;
    background-color: var(--tblr-bg-surface-secondary);
    background-image:
        radial-gradient(110% 140% at 12% 0%, color-mix(in srgb, var(--ft-thumb, var(--ft-teal)) 62%, transparent), transparent 62%),
        linear-gradient(135deg, color-mix(in srgb, var(--ft-thumb, var(--ft-teal)) 34%, transparent), transparent 78%);
}

.ft-thumb-lg {
    height: 12rem;
}

/* Tints match the three brand accents in theme.css. */
.ft-thumb-teal  { --ft-thumb: var(--ft-teal-bright); }
.ft-thumb-gold  { --ft-thumb: var(--ft-gold); }
.ft-thumb-ocean { --ft-thumb: var(--ft-ocean-high); }

/* Lets a flex child shrink far enough for text-truncate to take effect. */
.min-w-0 {
    min-width: 0;
}

/* ---------------------------------------------------------- post body ---
 * Styling for Markdown rendered by PostStore. Scoped to .ft-prose so post
 * content cannot leak styles into the surrounding chrome.
 */
.ft-prose {
    font-size: 1.0625rem;
    line-height: 1.7;
}

.ft-prose > :first-child {
    margin-top: 0;
}

.ft-prose h2 {
    margin-top: 2rem;
    margin-bottom: .75rem;
    font-size: 1.5rem;
}

.ft-prose h3 {
    margin-top: 1.5rem;
    margin-bottom: .5rem;
    font-size: 1.25rem;
}

.ft-prose p,
.ft-prose ul,
.ft-prose ol {
    margin-bottom: 1.15rem;
}

.ft-prose li + li {
    margin-top: .35rem;
}

.ft-prose img {
    max-width: 100%;
    height: auto;
    border-radius: var(--tblr-border-radius);
}

.ft-prose table {
    width: 100%;
    margin-bottom: 1.5rem;
    border-collapse: collapse;
}

.ft-prose th,
.ft-prose td {
    padding: .5rem .75rem;
    border-bottom: var(--tblr-border-width) solid var(--tblr-border-color);
    text-align: left;
}

.ft-prose thead th {
    color: var(--ft-gold);
    font-size: .8125rem;
    text-transform: uppercase;
    letter-spacing: .03em;
}

.ft-prose blockquote {
    margin: 1.5rem 0;
    padding: .25rem 0 .25rem 1rem;
    border-inline-start: 3px solid var(--ft-gold);
    color: var(--tblr-secondary);
}

.ft-prose pre {
    padding: 1rem;
    border: var(--tblr-border-width) solid var(--tblr-border-color);
    border-radius: var(--tblr-border-radius);
    background: var(--tblr-bg-surface-secondary);
    overflow-x: auto;
}

/* Cover images reuse the placeholder thumbnail's aspect and cropping. */
.ft-thumb-img {
    height: 7rem;
    object-fit: cover;
}

.ft-thumb-img.ft-thumb-lg {
    height: 12rem;
}

/* -------------------------------------------------------- class guides ---
 * The guide hero tints itself with the class colour via --ft-class, which the
 * wow-<slug> class on the wrapper sets.
 */
.ft-guide-hero {
    background:
        radial-gradient(85% 130% at 10% 0%,
            color-mix(in srgb, var(--ft-class, var(--ft-teal)) 22%, transparent), transparent 64%),
        var(--tblr-bg-surface);
}

.ft-guide-icon {
    border-radius: var(--tblr-border-radius);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--ft-class, var(--tblr-border-color)) 70%, transparent);
}

/* Ability cards get a gold left edge so they read as a distinct block type. */
.ft-ability-card {
    border-inline-start: 3px solid color-mix(in srgb, var(--ft-gold) 55%, transparent);
}

/* Keeps the reference sidebar in view while reading a long info page. */
@media (min-width: 992px) {
    .ft-sticky-aside {
        position: sticky;
        top: 5rem;
    }
}

/* ------------------------------------------------------ article headers ---
 * Shared by news posts and info pages. The goal is a header that reads as a
 * distinct block rather than a run of stacked text: an eyebrow rule, a tight
 * headline, a lead paragraph at reduced emphasis, then a bounded meta strip.
 */
.ft-article-header {
    margin-bottom: 2rem;
}

/* Category eyebrow with a short gold rule, echoing the cover-card treatment. */
.ft-eyebrow {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin-bottom: .875rem;
    color: var(--ft-gold);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.ft-eyebrow::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: linear-gradient(to right,
        color-mix(in srgb, var(--ft-gold) 45%, transparent), transparent);
}

.ft-article-title {
    margin-bottom: .75rem;
    font-size: clamp(1.9rem, 1.2rem + 2.4vw, 3rem);
    font-weight: 800;
    line-height: 1.12;
    text-wrap: balance;
}

.ft-article-lead {
    max-width: 62ch;
    margin-bottom: 1.5rem;
    color: var(--tblr-secondary);
    font-size: 1.15rem;
    line-height: 1.55;
    text-wrap: pretty;
}

/* Meta strip: hairline top and bottom, dot separators between items. */
.ft-article-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem 1rem;
    padding: .75rem 0;
    border-top: var(--tblr-border-width) solid var(--tblr-border-color);
    border-bottom: var(--tblr-border-width) solid var(--tblr-border-color);
    color: var(--tblr-secondary);
    font-size: .875rem;
}

.ft-article-meta > * {
    display: flex;
    align-items: center;
    gap: .375rem;
}

.ft-article-meta .ft-meta-author {
    color: var(--tblr-body-color);
    font-weight: 600;
}

/* ---------------------------------------------------------- prose headings
 * Body headings get more definition: a gold marker on h2 so section starts are
 * scannable, and a clearer size step down to h3.
 */
.ft-prose h2 {
    position: relative;
    margin-top: 2.5rem;
    padding-top: 1.25rem;
    border-top: var(--tblr-border-width) solid var(--tblr-border-color);
    font-size: 1.6rem;
    font-weight: 700;
}

.ft-prose h2::before {
    content: "";
    position: absolute;
    top: -1px;
    inset-inline-start: 0;
    width: 2.5rem;
    height: 2px;
    background: var(--ft-gold);
}

.ft-prose h3 {
    margin-top: 1.75rem;
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--tblr-body-color);
}

/* The first heading in a body should not carry a rule above it. */
.ft-prose > h2:first-child {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

.ft-prose > h2:first-child::before {
    display: none;
}

/* -------------------------------------------------------- consent banner ---
 * A bottom sheet rather than a modal: it must be dismissible but must not block
 * reading, and a blocking overlay on a content site is both hostile and bad for
 * the crawlers that render pages.
 */
.ft-consent {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: 1040;
    padding: 1rem;
    border-top: var(--tblr-border-width) solid var(--tblr-border-color);
    background: var(--tblr-bg-surface);
    box-shadow: 0 -8px 24px rgba(0, 0, 0, .28);
}

.ft-consent[hidden] {
    display: none;
}

.ft-consent-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    max-width: 1320px;
    margin-inline: auto;
}

.ft-consent-text {
    flex: 1 1 22rem;
    font-size: .875rem;
    color: var(--tblr-secondary);
}

.ft-consent-heading {
    margin-bottom: .25rem;
    color: var(--ft-gold);
    font-weight: 700;
}

.ft-consent-actions {
    display: flex;
    flex: 0 0 auto;
    gap: .5rem;
}

@media (max-width: 575.98px) {
    .ft-consent-actions {
        width: 100%;
    }

    .ft-consent-actions .btn {
        flex: 1 1 0;
    }
}
