/**
 * Emberloom Books Catalog — frontend styles. Prefix: ebc-
 *
 * The banner pair arrives as two custom properties:
 *   --ebc-banner-bg   --ebc-banner-text
 * On single book pages they are set at :root; the Banner widget and loop
 * cards scope them locally. Components consume them with palette fallbacks,
 * so everything works with no pair assigned.
 */

/* ---------------------------------------------------------- utilities
 * For Elementor / theme elements: add the class in Advanced → CSS Classes
 * to force the element onto the book's pair, overriding template styling. */
.ebc-pair-text { color: var(--ebc-banner-text, inherit) !important; }
.ebc-pair-bg   { background-color: var(--ebc-banner-bg, transparent) !important; }
.ebc-pair-fill {
    color: var(--ebc-banner-text, inherit) !important;
    background-color: var(--ebc-banner-bg, transparent) !important;
}

/* ------------------------------------------------------------- banner */
.ebc-banner {
    position: relative;
    overflow: hidden;
    /* Colour and image are separate properties so a gradient can be painted
     * over the pair colour without the pair token losing its value — other
     * components read --ebc-banner-bg for their own contrast decisions. */
    background-color: var(--ebc-banner-bg, transparent);
    background-image: var(--ebc-banner-bg-image, none);
    color: var(--ebc-banner-text, inherit);
}

.ebc-banner__image {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: var(--ebc-banner-image-position, center);
    opacity: var(--ebc-banner-image-opacity, 1);
}

/* Direction, gap and cross-axis alignment are custom properties so the
 * widget can set them per breakpoint — stack the cover above the copy on
 * a phone, keep it beside on desktop. Left alone, the banner behaves as it
 * always has: cover beside the copy, wrapping under it when it no longer
 * fits (--ebc-banner-copy-basis is the width at which that happens). */
.ebc-banner__inner {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    flex-direction: var(--ebc-banner-direction, row);
    /* Column and row gaps are separate: welded together, the space above a
     * description below the banner could only ever be added to, never
     * reduced, because it was whatever the cover-to-text gap happened to be. */
    column-gap: var(--ebc-banner-gap, 2rem);
    row-gap: var(--ebc-banner-row-gap, var(--ebc-banner-gap, 2rem));
    align-items: var(--ebc-banner-cross-align, center);
    padding: clamp(2rem, 6vw, 4rem);
}

.ebc-banner__cover {
    flex: 0 0 auto;
    max-width: min(280px, 40%);
}

.ebc-banner__cover img {
    display: block;
    width: 100%;
    height: auto;
    /* Stock shadow for shortcode / template output. The Elementor widget
     * clears it (below) so its own Box Shadow control is the only thing
     * painting one there — including when it is switched off. */
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25);
}

.ebc-banner-widget .ebc-banner__cover img {
    box-shadow: none;
}

/* Inside Elementor the Advanced tab owns spacing, the way it does on every
 * other widget. The padding above is for shortcode and template output,
 * which has no builder to set it — left in place here it would sit inside
 * whatever Advanced added, so the two stacked and Advanced could never take
 * spacing back down. Same reasoning as the cover shadow above. */
.ebc-banner-widget .ebc-banner__inner {
    padding: 0;
}

.ebc-banner__text {
    /* width applies on the cross axis once the banner is stacked, so the
     * copy fills the banner instead of shrink-wrapping. It is ignored while
     * the copy is a row item, where the flex basis is the main size. */
    flex: 1 1 var(--ebc-banner-copy-basis, 260px);
    width: 100%;
    min-width: 0;
}

.ebc-banner__title {
    margin: 0;
    color: var(--ebc-banner-text, inherit);
    font-size: clamp(1.8rem, 4vw, 3rem);
    line-height: 1.15;
    /* A thirteen-word title with a long word in it must not run off the side
     * of a phone, whatever size it is set to. balance evens out the lines of
     * a heading that wraps; both degrade to nothing where unsupported. */
    overflow-wrap: break-word;
    text-wrap: balance;
}

.ebc-banner__subtitle {
    margin: var(--ebc-banner-subtitle-gap, 0.75rem) 0 0;
    color: var(--ebc-banner-text, inherit);
    font-size: clamp(1.05rem, 2vw, 1.35rem);
    /* Subtitles run long — "The Lessons of Daring Leadership, the Tenacity of
     * Paradox, and the Wisdom of the Human Spirit" is a real one. pretty
     * rather than balance: no line cap, and it kills orphans. */
    overflow-wrap: break-word;
    text-wrap: pretty;
}

/* A description inside the banner. The shell is a flex child with a
 * full-width basis, so it always lands on its own line under both the cover
 * and the copy, whatever arrangement the widget picked — the banner's own
 * gap spaces it. The width control clamps the `.ebc-description` inside it,
 * never the shell: a narrowed flex item would fit back onto the cover's
 * line and the description would end up beside the cover, not under it.
 * Positioned in the copy column instead, the shell is an ordinary block and
 * the basis is ignored. */
.ebc-banner__description {
    color: var(--ebc-banner-text, inherit);
    min-width: 0;
}

.ebc-banner__description--full {
    flex: 0 0 100%;
    width: 100%;
}

/* -------------------------------------------------------------- cover
 * The standalone cover widget. Same frame the banner and cards use, with
 * nothing around it. */
.ebc-cover__link { display: block; text-decoration: none; }

.ebc-cover__frame {
    display: block;
    max-width: 100%;
    aspect-ratio: var(--ebc-cover-ratio, 2 / 3);
    overflow: hidden;
    transition: transform 0.3s ease;
}

.ebc-cover__frame img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ebc-cover-hover-grow .ebc-cover__frame:hover { transform: scale(1.04); }
.ebc-cover-hover-shrink .ebc-cover__frame:hover { transform: scale(0.96); }

/* --------------------------------------------------- banner extras
 * Authors and buy links are opt-in inside the banner, so they inherit the
 * pair's text colour rather than the page's. */
.ebc-banner__text .ebc-authors,
.ebc-banner__text .ebc-buy,
.ebc-banner__text .ebc-banner__description {
    margin-top: var(--ebc-banner-extras-gap, 1.25rem);
    color: var(--ebc-banner-text, inherit);
}

.ebc-banner__text .ebc-buy__label {
    font-size: 1rem;
    margin: 0 0 0.6rem;
    /* Follows the same alignment as the buttons below it. */
    text-align: var(--ebc-banner-extras-text-align, inherit);
}

.ebc-banner__text .ebc-buy__list {
    justify-content: var(--ebc-banner-extras-justify, flex-start);
}

/* ---------------------------------------------------------- buy links */
.ebc-buy {
    /* Two colour tokens, not one. --ebc-buy-fg is the buttons; the title and
     * region titles take --ebc-buy-label-fg. They were the same token, so a
     * Link Color control repainted the "Buy the Book" heading as well. */
    --ebc-buy-fg: var(--ebc-banner-text, currentColor);
    --ebc-buy-label-fg: var(--ebc-banner-text, currentColor);
    --ebc-buy-border: var(--ebc-buy-fg);
    --ebc-buy-bg: transparent;
    --ebc-buy-hover-bg: var(--ebc-buy-fg);
    --ebc-buy-hover-fg: var(--ebc-banner-bg, #fff);
}

@supports (color: color-mix(in srgb, red 50%, transparent)) {
    .ebc-buy { --ebc-buy-border: color-mix(in srgb, var(--ebc-buy-fg) 45%, transparent); }
}

.ebc-buy__label {
    font-size: 1rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    margin: 0 0 var(--ebc-buy-label-gap, 1rem);
    color: var(--ebc-buy-label-fg);
}

.ebc-buy__region + .ebc-buy__region { margin-top: 1.5rem; }

.ebc-buy__region-title {
    font-size: 0.8rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    margin: 0 0 0.6rem;
    color: var(--ebc-buy-label-fg);
}

.ebc-buy__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.ebc-buy__link {
    display: inline-block;
    padding: 0.55rem 1.1rem;
    /* Transparent by default, but a real property so the button can be given
     * a solid fill — without one there is no way to colour it at all. */
    background-color: var(--ebc-buy-bg, transparent);
    border: 1px solid var(--ebc-buy-border);
    border-radius: 2rem;
    font-size: 0.9rem;
    line-height: 1.2;
    text-decoration: none;
    color: var(--ebc-buy-fg);
    transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

.ebc-buy__link:hover,
.ebc-buy__link:focus-visible {
    background: var(--ebc-buy-hover-bg);
    color: var(--ebc-buy-hover-fg);
    border-color: var(--ebc-buy-hover-bg);
}

.ebc-buy__link:focus-visible {
    outline: 2px solid var(--ebc-buy-fg);
    outline-offset: 2px;
}

/* -------------------------------------------------------------- quotes */
.ebc-quotes { display: grid; gap: 1.75rem; }

.ebc-quote {
    margin: 0;
    padding: 0;
    border: 0;
}

.ebc-quote__text {
    margin: 0;
    font-size: 1.1rem;
    line-height: 1.6;
    font-style: italic;
}

.ebc-quote__text::before { content: "\201C"; }
.ebc-quote__text::after  { content: "\201D"; }

.ebc-quote__attribution {
    margin-top: 0.6rem;
    font-size: 0.9rem;
}

.ebc-quote__name { font-style: normal; font-weight: 600; }

.ebc-quote__name a {
    color: inherit;
    text-underline-offset: 2px;
}

.ebc-quote__credential::before { content: ", "; }

.ebc-featured-quote .ebc-quote--featured .ebc-quote__text {
    font-size: clamp(1.3rem, 2.5vw, 1.75rem);
    line-height: 1.45;
}

/* ------------------------------------------------------------- authors */
.ebc-authors__line { margin: 0; }

.ebc-authors__link {
    color: inherit;
    text-underline-offset: 2px;
}

.ebc-authors__card {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    margin-top: 1rem;
}

.ebc-authors__photo {
    width: 64px;
    height: 64px;
    object-fit: cover;
    border-radius: 50%;
    flex: 0 0 auto;
}

.ebc-authors__name { font-weight: 600; }

.ebc-authors__bio {
    margin: 0.25rem 0 0;
    font-size: 0.95rem;
}

/* ------------------------------------------------------------ progress */
.ebc-progress { max-width: 32rem; }

.ebc-progress__meta {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.4rem;
    font-size: 0.85rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.ebc-progress__track {
    height: 0.6rem;
    border-radius: 1rem;
    background-color: var(--ebc-progress-track, rgba(128, 128, 128, 0.25));
    overflow: hidden;
}

.ebc-progress__bar {
    height: 100%;
    border-radius: inherit;
    background-color: var(--ebc-progress-fill, var(--ebc-banner-bg, currentColor));
    transition: width 0.4s ease;
}

/* ---------------------------------------------------------- book lists */
.ebc-books-section + .ebc-books-section { margin-top: 3rem; }

/* Follows the surrounding text color — deliberately not the theme's h2
 * heading color. Restyle via the widget's List Heading controls. */
.ebc-books-section__title {
    margin: 0 0 1.25rem;
    color: inherit;
}

.ebc-books-grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(var(--ebc-grid-cols, 3), minmax(0, 1fr));
    gap: 2rem;
}

/* The column count arrives as a class so three layers can stack in the right
 * order: these class rules, then the narrow-screen fallbacks below them at
 * equal specificity, then the widget's own per-device rules, which carry the
 * Elementor wrapper and outrank both. An inline style — which is what the
 * count used to be — outranks all three, which is why the responsive Columns
 * control did nothing below 900px. */
.ebc-books-grid--cols-1 { --ebc-grid-cols: 1; }
.ebc-books-grid--cols-2 { --ebc-grid-cols: 2; }
.ebc-books-grid--cols-3 { --ebc-grid-cols: 3; }
.ebc-books-grid--cols-4 { --ebc-grid-cols: 4; }
.ebc-books-grid--cols-5 { --ebc-grid-cols: 5; }
.ebc-books-grid--cols-6 { --ebc-grid-cols: 6; }

/* Fallbacks for shortcode and template output, which has no widget to say
 * what a phone should do. The widget overrides these per device. */
@media (max-width: 900px) {
    .ebc-books-grid { --ebc-grid-cols: 2; }
}

@media (max-width: 560px) {
    .ebc-books-grid { --ebc-grid-cols: 1; }
}

.ebc-book-card__media {
    display: block;
}

.ebc-book-card__link {
    display: inline-block;
    text-decoration: none;
    color: inherit;
}

.ebc-book-card__cover {
    display: block;
    max-width: 100%;
    /* Per-book ratio from the cover's own dimensions; 2:3 for placeholders. */
    aspect-ratio: var(--ebc-cover-ratio, 2 / 3);
    overflow: hidden;
    /* No background behind real covers — transparent PNGs must not pick up
     * a visible ground. Placeholders and the widget's Image Background
     * control are the only ways this box gets a fill.
     * The gap to the card text is a property so the widget's Gap to Text
     * control can drive it in both layouts. */
    margin-bottom: var(--ebc-cover-gap, 0.85rem);
    transition: transform 0.3s ease;
}

/* object-fit is themable so square covers can use `contain` (letterboxed on
 * the pair background) instead of being cropped into the box. */
.ebc-book-card__cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Hover scales the whole cover container (shadow and border included),
 * never the image inside it. Opt-in via grid modifier. */
.ebc-books-grid--hover-grow .ebc-book-card__media:hover .ebc-book-card__cover {
    transform: scale(1.04);
}

.ebc-books-grid--hover-shrink .ebc-book-card__media:hover .ebc-book-card__cover {
    transform: scale(0.96);
}

/* Rows layout: image beside copy, one card per row. */
.ebc-books-grid--rows {
    grid-template-columns: 1fr;
}

.ebc-books-grid--rows .ebc-book-card {
    display: flex;
    /* Wrapping is what lets a full-width description drop onto its own line
     * under the cover and the copy both. The cover and the copy never wrap
     * against each other: the copy shrinks instead (flex 1 1 0). */
    flex-wrap: wrap;
    /* Direction is a property so the widget can stack the card per device:
     * beside the text on desktop, cover above it on a phone, where a third
     * of the width is too small a cover to be worth showing. */
    flex-direction: var(--ebc-row-direction, row);
    align-items: flex-start;
    /* Same property as the grid gap below the cover — beside it here. */
    column-gap: var(--ebc-cover-gap, 1.5rem);
    /* Only wanted once stacked; beside the text the columns supply it. */
    row-gap: var(--ebc-row-gap, 0);
}

.ebc-books-grid--rows .ebc-book-card__media {
    flex: 0 0 auto;
    width: var(--ebc-row-media-width, 30%);
    max-width: var(--ebc-row-media-max, 220px);
}

.ebc-books-grid--rows .ebc-book-card__cover {
    width: 100%;
    margin-bottom: 0;
}

.ebc-books-grid--rows .ebc-book-card__body {
    /* Basis 0 rather than auto: the row wraps (so a full-width description
     * can drop below the cover), and an auto basis is the copy's max-content
     * width, which on a narrow screen is wide enough to wrap the copy itself
     * under the cover. At 0 it never breaks the line and still takes all the
     * space left beside the cover. */
    flex: 1 1 0;
    min-width: 0;
}

/* A third of a phone screen is not a book cover, it is a thumbnail. Stacked
 * is the sensible default at this width; the widget overrides it per device.
 * Properties rather than the concrete declarations, so it can. */
@media (max-width: 560px) {
    .ebc-books-grid--rows .ebc-book-card {
        --ebc-row-direction: column;
        --ebc-row-media-width: 100%;
        --ebc-row-media-max: none;
        --ebc-row-gap: var(--ebc-cover-gap, 1.5rem);
    }
}

/* Divider: a horizontal rule above every book after the first, for lists
 * that carry no card background or border. Drawn as an out-of-flow
 * pseudo-element rather than a border-top so it can be narrower than the
 * card, can be aligned, and never collides with the card's own Border
 * control. Space above the rule is the grid gap; space below it is the
 * card's top padding (the widget's Divider Gap). */
.ebc-books-grid--divided .ebc-book-card {
    position: relative;
}

.ebc-books-grid--divided .ebc-book-card + .ebc-book-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    width: var(--ebc-divider-width, 100%);
    /* auto/auto centers the rule; the widget sets one side to 0 to align it. */
    margin-left: var(--ebc-divider-offset-start, auto);
    margin-right: var(--ebc-divider-offset-end, auto);
    border-top: var(--ebc-divider-weight, 1px) var(--ebc-divider-style, solid) var(--ebc-divider-color, currentColor);
}

.ebc-book-card__link:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 3px;
}

.ebc-book-card__cover--placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    text-align: center;
    background-color: var(--ebc-banner-bg, rgba(128, 128, 128, 0.12));
    color: var(--ebc-banner-text, inherit);
    font-size: 0.95rem;
}

.ebc-book-card__title {
    display: block;
    font-weight: 700;
    font-size: 1.05rem;
    line-height: 1.3;
    /* Same reason as the banner title: a card column is narrower still. */
    overflow-wrap: break-word;
}

.ebc-book-card__subtitle {
    display: block;
    margin-top: 0.2rem;
    font-size: 0.9rem;
    overflow-wrap: break-word;
}

.ebc-book-card .ebc-authors,
.ebc-book-card .ebc-progress { margin-top: 0.5rem; }

.ebc-book-card__description {
    margin-top: var(--ebc-card-description-gap, 0.85rem);
}

/* Under the cover and the copy both, rather than beside the cover. The card
 * is a flex row only in the Rows layout; in a grid it is an ordinary block,
 * where the basis is ignored and the description simply follows the copy.
 * As in the banner, the width control clamps the `.ebc-description` inside
 * the shell rather than the shell itself, which would let the description
 * fit back onto the cover's line. */
.ebc-book-card__description--full {
    flex: 0 0 100%;
    width: 100%;
}

/* Buy buttons on a card take the card's own text color, not the pair's
 * banner text: a card carries the pair as custom properties but paints no
 * pair background behind them, so a pair meant for a dark banner would put
 * a near-invisible button on the page background. */
.ebc-book-card .ebc-buy {
    --ebc-buy-fg: currentColor;
    --ebc-buy-hover-fg: #fff;
    margin-top: var(--ebc-card-buy-gap, 0.85rem);
}

/* text-align does not move flex items, so the buttons get their own. */
.ebc-book-card .ebc-buy__list {
    justify-content: var(--ebc-card-buy-justify, flex-start);
}

.ebc-book-card .ebc-progress__meta { text-transform: none; letter-spacing: 0; }

/* ------------------------------------------------- fallback single page */
.ebc-single__body {
    max-width: 42rem;
    margin: 0 auto;
    padding: 2.5rem 1.25rem;
    display: grid;
    gap: 2.5rem;
}

.ebc-representation {
    margin: 0;
    font-size: 0.95rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.ebc-back-link a {
    /* No styling opinion here — the link takes whatever the theme gives its
     * links. `color: inherit` was the actual defect: it forced the link to
     * the body copy's colour, so on a theme that also strips underlines
     * nothing distinguished it from plain text. Underlining it was the
     * wrong half of the fix; letting the theme's link colour through is
     * the right one. */
    text-underline-offset: 3px;
}

/* An empty block still claims a grid row and the gaps either side of it —
 * roughly 5rem of dead space above a book with no description yet. */
.ebc-single__body > :empty { display: none; }

.ebc-description > :first-child { margin-top: 0; }
.ebc-description > :last-child { margin-bottom: 0; }

/* ------------------------------------------------------ reduced motion */
@media (prefers-reduced-motion: reduce) {
    .ebc-buy__link,
    .ebc-progress__bar,
    .ebc-book-card__cover,
    .ebc-cover__frame { transition: none; }
}
