/* ============================================================
 * Custom utility classes - replacing inline style="" attributes
 * for CSP compliance (style-src without 'unsafe-inline').
 * ============================================================ */

/* --- Cursor --- */
.cursor-pointer       { cursor: pointer; }
.cursor-pointer-dashed { cursor: pointer; border-style: dashed !important; }
.cursor-grab          { cursor: grab; }

/* --- White-space --- */
.ws-pre-line { white-space: pre-line; }
.ws-pre-wrap { white-space: pre-wrap; }

/* --- Font sizes below Bootstrap's fs-6 (1rem) --- */
.fs-xs   { font-size: .75rem; }  /* 12px */
.fs-xxs  { font-size: .7rem; }   /* ~11px */
.fs-xxxs { font-size: .68rem; }  /* ~10.9px */
.fs-sm   { font-size: .8rem; }   /* ~13px */
.fs-badge { font-size: .85rem; } /* event badges */

/* --- Font sizes above 1rem --- */
.fs-1_2  { font-size: 1.2rem; }
.fs-3rem { font-size: 3rem; }
.fs-4rem { font-size: 4rem; }

/* --- Scroll boxes (max-height + overflow-y:auto) --- */
.scroll-box-sm  { max-height: 150px; overflow-y: auto; }
.scroll-box     { max-height: 200px; overflow-y: auto; }
.scroll-box-lg  { max-height: 250px; overflow-y: auto; }
.scroll-box-xl  { max-height: 260px; overflow-y: auto; }
.scroll-box-md  { max-height: 220px; overflow-y: auto; }
.scroll-box-xxl { max-height: 420px; overflow-y: auto; }
.scroll-box-240 { max-height: 240px; overflow-y: auto; }
.scroll-box-300 { max-height: 300px; overflow-y: auto; }
.scroll-box-160 { max-height: 160px; overflow-y: auto; }
.clip-h-120     { max-height: 120px; overflow: hidden; }

/* --- Letter spacing + monospace (e.g. verification codes) --- */
.tracking-wide-mono   { letter-spacing: 0.5em; font-family: monospace; }
.tracking-normal-mono { letter-spacing: 0.3em; font-family: monospace; }
.tracking-sm          { letter-spacing: 0.15em; }
.tracking-xs          { letter-spacing: 0.05em; }

/* --- Floating action button (scroll-to-top, etc.) --- */
.floating-action {
    position: fixed;
    bottom: 30px;
    right: 30px;
    z-index: 9999;
}

/* --- Card containers --- */
.card-narrow     { max-width: 420px; border-radius: 12px; }
.card-narrow-w   { max-width: 420px; width: 100%; border-radius: 12px; }
.card-medium     { max-width: 520px; border-radius: 12px; }
.card-wide       { max-width: 440px; border-radius: 12px; }

/* --- Preview / overflow boxes --- */
.preview-box     { height: 120px; overflow: hidden; }

/* --- Embed / iframe containers --- */
.iframe-full     { width: 100%; height: 76vh; border: 0; }

/* --- Column widths (admin tables) --- */
.col-w-38   { width: 38px; }
.col-w-60   { width: 60px; }
.col-w-70   { width: 70px; }
.col-w-80   { width: 80px; }
.col-w-88   { width: 88px; }
.col-w-100  { width: 100px; }
.col-w-110  { width: 110px; }
.col-w-120  { width: 120px; }
.col-w-130  { width: 130px; }
.col-w-160  { width: 160px; }
.col-w-170  { width: 170px; }
.col-w-220  { width: 220px; }
.col-w-250  { width: 250px; }
.col-w-340  { width: 340px; }

/* --- Widths in rem (form controls / select boxes) --- */
.w-7rem   { width: 7rem; }
.w-6rem   { width: 6rem; }
.w-11rem  { width: 11rem; }
.w-14rem  { width: 14rem; }
.w-18rem  { width: 18rem; }
.w-280px  { width: 280px; }

/* --- Percentage widths --- */
.col-w-38p { width: 38%; }

/* --- Min-widths --- */
.min-w-50   { min-width: 50px; }
.min-w-0    { min-width: 0; }
.min-w-140  { min-width: 140px; }
.min-w-170  { min-width: 170px; }
.min-w-180  { min-width: 180px; }
.min-w-220  { min-width: 220px; }
.min-w-260  { min-width: 260px; }
.min-w-280  { min-width: 280px; }

/* --- Max-widths --- */
.mw-120  { max-width: 120px; }
.mw-150  { max-width: 150px; }
.mw-180  { max-width: 180px; }
.mw-200  { max-width: 200px; }
.mw-250  { max-width: 250px; }
.mw-260  { max-width: 260px; }
.mw-320  { max-width: 320px; }
.mw-350  { max-width: 350px; }
.mw-400  { max-width: 400px; }
.mw-500  { max-width: 500px; }
.mw-640  { max-width: 640px; }
.mw-680  { max-width: 680px; }
.mw-700  { max-width: 700px; }
.mw-720  { max-width: 720px; }
.mw-780  { max-width: 780px; }
.mw-800  { max-width: 800px; }
.mw-960  { max-width: 960px; }
.mw-1000 { max-width: 1000px; }
.mw-110  { max-width: 110px; }
.mw-160  { max-width: 160px; }
.mw-840  { max-width: 840px; }
.mw-980  { max-width: 980px; }
.mw-14rem { max-width: 14rem; }
.mw-18rem { max-width: 18rem; }

/* --- Misc single-use utilities --- */
.rounded-card-top { border-radius: 12px 12px 0 0; }
.rounded-card     { border-radius: 12px; }
.h-4px            { height: 4px; }
.h-6px            { height: 6px; }
.h-8px            { height: 8px; }
.h-20px           { height: 20px; }
.min-h-120        { min-height: 120px; }
.min-h-180        { min-height: 180px; }
.min-h-220        { min-height: 220px; }
.min-h-240        { min-height: 240px; }
.min-h-350        { min-height: 350px; }
.min-h-60vh       { min-height: 60vh; }
.z-10             { z-index: 10; }
.z-1055           { z-index: 1055; }
.z-1090           { z-index: 1090; }
.z-9999           { z-index: 9999; }
.offscreen-honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    opacity: 0;
}
.verification-code-input {
    max-width: 180px;
    letter-spacing: 4px;
    font-family: monospace;
}

/* --- Color swatch dots --- */
.swatch-dot-sm {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
}
.swatch-dot {
    display: inline-block;
    width: 20px;
    height: 20px;
    border-radius: 50%;
}
.swatch-dot-xs {
    width: .6rem;
    height: .6rem;
}

/* --- Thumbnail / image constraints --- */
.thumb-xs  { max-height: 60px; width: auto; }
.thumb-sm  { max-height: 80px; width: auto; }
.thumb-90  { max-height: 90px; width: auto; }
.thumb-md  { max-height: 100px; width: auto; }
.thumb-lg  { max-height: 150px; width: auto; }
.thumb-xl  { height: 150px; width: auto; }
.thumb-cover-sm  { max-height: 120px; max-width: 100%; object-fit: cover; }
.thumb-cover-md  { max-height: 150px; border-radius: 4px; object-fit: cover; }
.thumb-60x100    { height: 60px; width: 100px; object-fit: cover; border-radius: 4px; }

/* --- Admin icon/avatar sizing --- */
.avatar-sq-sm   { width: 36px; }
.avatar-sq-xs   { width: 35px; height: 30px; padding: 2px; }
.avatar-sq-2_5  { width: 2.5rem; min-width: 2.5rem; }
.icon-sq-160    { height: 160px; width: 160px; }

/* --- Progress bar height --- */
.progress-thin        { height: 4px; border-radius: 2px; transition: all 0.3s; }
.progress-bar-dynamic { width: var(--progress-width, 0%); }

/* --- CSP-safe dynamic colour utilities (values come from nonce'd style rules) --- */
.dynamic-bg-badge {
    background-color: var(--dynamic-bg-color, #6c757d);
    color: #fff;
}

/* --- Forum presentation helpers --- */
.forum-avatar-icon-lg { font-size: 96px; }
.forum-avatar-icon-md { font-size: 48px; }
.forum-you-badge      { font-size: 0.6em; }

/* --- Editor / form containers --- */
.editor-frame {
    width: 100%;
    min-height: 640px;
    border: 1px solid #dee2e6;
    border-radius: .5rem;
    background: #fff;
}

.email-template-preview-frame {
    min-height: 320px;
    background: #fff;
}

/* --- Scrollable dropdown --- */
.dropdown-scroll {
    min-width: 340px;
    max-height: 420px;
    overflow-y: auto;
}
.dropdown-anchored {
    right: 0;
    left: auto;
    top: 100%;
}

/* --- Scroll box with border (form fields) --- */
.scroll-box-bordered {
    max-height: 260px;
    overflow-y: auto;
    border: 1px solid #dee2e6;
    border-radius: .375rem;
    padding: .5rem .75rem;
}

/* --- Multi-column layout --- */
.columns-3 {
    columns: 3;
    column-gap: 1rem;
    max-height: 200px;
    overflow-y: auto;
}

/* --- Strong danger text (deeper red than Bootstrap's text-danger) --- */
.text-danger-strong { color: #b91c1c; }

/* --- Spacing fillers Bootstrap doesn't cover (.35rem / .75rem) --- */
.mt-035 { margin-top: 0.35rem; }
.mt-075 { margin-top: 0.75rem; }

/* --- Auto-fit grid (220px min, 1fr max), gap 1rem --- */
.form-grid-220 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
    align-items: start;
}

/* --- Sticky offsets --- */
.sticky-top-70 { position: sticky; top: 96px; }
.sticky-top-80 { position: sticky; top: 80px; }

/* --- Resource section anchors --- */
.letter-section {
    scroll-margin-top: var(--resource-anchor-offset, 96px);
}

/* --- Full-bleed image display --- */
.img-contain-full {
    display: block;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    height: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* --- Notification centre toast ---
   Lives here (not style.css) because the admin panel loads utilities.css but
   not style.css; the in-app registration/notification toasts are admin-facing,
   so the designed styling has to be in a stylesheet both layouts load. All
   colour references fall back to a safe green when a theme variable is absent
   (e.g. inside the admin panel, which does not set --site-accent). */
.notif-toast {
    border: 1px solid var(--bs-border-color-translucent, rgba(0,0,0,.12));
    border-left: 4px solid var(--site-accent, #198754);
    border-radius: 0.5rem;
    box-shadow: 0 8px 28px rgba(0,0,0,.13), 0 2px 6px rgba(0,0,0,.07);
    min-width: 280px;
    max-width: 340px;
    overflow: hidden;
    animation: notif-slide-in 0.28s ease-out;
}
.notif-toast__header {
    background: transparent;
    border-bottom: 1px solid var(--bs-border-color-translucent, rgba(0,0,0,.08));
    padding: 0.55rem 0.75rem;
    gap: 0.45rem;
}
.notif-toast__icon {
    color: var(--site-accent, #198754);
    display: flex;
    align-items: center;
    flex-shrink: 0;
}
.notif-toast__title {
    font-size: 0.84rem;
    font-weight: 600;
}
.notif-toast__body {
    padding: 0.6rem 0.75rem 0.55rem;
    font-size: 0.84rem;
}
.notif-toast__text {
    color: var(--bs-secondary-color, #6c757d);
    line-height: 1.45;
    margin: 0;
}
.notif-toast__link {
    display: inline-block;
    margin-top: 0.55rem;
    padding: 0.22rem 0.8rem;
    font-size: 0.77rem;
    font-weight: 500;
    color: var(--site-accent, #198754);
    background: rgba(var(--site-accent-rgb, 25 135 84), 0.08);
    border: 1px solid rgba(var(--site-accent-rgb, 25 135 84), 0.25);
    border-radius: 20px;
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
}
.notif-toast__link:hover,
.notif-toast__link:focus {
    background: var(--site-accent, #198754);
    color: var(--site-on-accent, #fff);
    text-decoration: none;
}
.notif-toast__progress {
    height: 3px;
    background: var(--site-accent, #198754);
    transform-origin: left;
    animation: notif-progress 8s linear forwards;
}
@keyframes notif-slide-in {
    from { opacity: 0; transform: translateX(32px); }
    to   { opacity: 1; transform: translateX(0); }
}
@keyframes notif-progress {
    from { transform: scaleX(1); }
    to   { transform: scaleX(0); }
}

/* --- MyAccount breadcrumb: no wrap, truncate current-page label on narrow viewports --- */
/* Needed because inline styles are blocked by CSP; this utility keeps the
   breadcrumb on one line and clips a long final segment (e.g. lesson-plan
   titles) without pushing other content off-screen on mobile.

   Below 576px the truncated crumb wraps to a second line with the full title
   visible - the `title` attribute alone isn't reachable by touch users. */
.breadcrumb-myaccount {
    min-width: 0;
}
.breadcrumb-myaccount__current {
    max-width: 60vw;
}
@media (max-width: 575.98px) {
    /* !important is required to defeat Bootstrap's `.flex-nowrap` and
       `.text-truncate` utilities, which themselves declare !important.
       Without it the partial's `class="... flex-nowrap text-truncate ..."`
       silently keeps the crumb on one line and ellipsis-clips it on
       mobile - i.e. this whole block becomes dead code. */
    .breadcrumb-myaccount { flex-wrap: wrap !important; }
    .breadcrumb-myaccount__current {
        flex-basis: 100%;
        max-width: 100% !important;
        white-space: normal !important;   /* overrides .text-truncate */
        overflow: visible !important;
        text-overflow: clip !important;
    }
    /* U3-2: the active crumb wraps to its own line via flex-basis:100%, but
       Bootstrap still injects the divider via `::before` on .breadcrumb-item +
       .breadcrumb-item, leaving an orphan ›/ at the start of the wrapped row.
       Suppress it on mobile only (desktop/tablet keep the inline divider). */
    .breadcrumb-myaccount > .breadcrumb-myaccount__current::before {
        content: none;
    }
}
