/* =====================================================================
   APP-UTILITIES.CSS

   `.apl-*`-prefixade utility-klasser och globala beteende-hooks som inte
   tillhör vendor-overrides eller komponent-mönster:

     1. prefers-reduced-motion baseline (FE2e — WCAG 2.3.3)
     2. .apl-skip-link (FE2d — WCAG 2.4.1)
     3. .apl-radio-label (override-säker label-stil för filter-radioknappar)
     4. .apl-modal-narrow/-medium/-wide/-fullscreen (FE15 modal density presets)
     5. Theme-picker shape-toggle active-state (synkad med global checkbox)

   Laddas EFTER `editor-overrides.css` men före `design-system.css`. Se
   `_Layout.cshtml` <head>-kommentaren för full load-order.
   ===================================================================== */

/* ---- 1. prefers-reduced-motion baseline (FE2e) --------------------- */
/* Globalt block som triggar när användaren har OS-inställningen
   "Reducera rörelser" på. `0.01ms` istället för `0` så JS-handlers som
   lyssnar på `transitionend`/`animationend`-events fortfarande fyr av —
   en `0`-duration skickar inget event och kan brytsönder Mud-/Bootstrap-
   komponenter som väntar på dem. `animation-iteration-count: 1` stoppar
   oändliga loopar (t.ex. Bootstrap-spinners). */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ---- 2. Skip-to-content-länk (FE2d) -------------------------------- */
/* Renderas som första element i varje layout (sidebar, navbar, tutor) i
   `MainLayout.razor`, pekar på `#apl-main-content`. Default off-screen
   via translateY; så fort tangentbordsfokus når den glider den fram i
   overlay-läget vid top-left. Tema-medveten via --saveb-bg/--saveb-text.
   Ligger ovanför allt annat (z-index: 9999) inkl. modal/toast-skikten. */
.apl-skip-link {
    position: fixed;
    top: 0;
    left: 0;
    transform: translateY(-110%);
    padding: 0.7rem 1.2rem;
    background: var(--saveb-bg);
    color: var(--saveb-text);
    font-weight: 600;
    text-decoration: none;
    border: 2px solid var(--text);
    border-radius: 0 0 6px 0;
    z-index: 9999;
    transition: transform 0.18s ease;
}

    .apl-skip-link:focus,
    .apl-skip-link:focus-visible {
        transform: translateY(0);
        outline: 3px solid var(--text);
        outline-offset: 2px;
    }

    .apl-skip-link:hover {
        background: var(--saveb-hover-bg);
        color: var(--saveb-hover-text);
    }

@media (prefers-reduced-motion: reduce) {
    .apl-skip-link {
        transition: none;
    }
}

/* Targeted main-content ska inte få visuell focus-outline när skip-länken
   triggar den (det är ett "programmatiskt" fokus, inte en interaktiv
   kontroll). tabindex=-1 + denna outline:none ger silent focus-jump. */
#apl-main-content:focus,
#apl-main-content:focus-visible {
    outline: none;
}

/* ---- 3. .apl-radio-label ------------------------------------------- */
/* Tvingad tema-färg på radio/checkbox-labels när andra regler tar över.
   Klassen läggs på <label> direkt efter <InputRadio>/<InputCheckbox> i
   filter-komponenter (t.ex. InternshipFilter). !important för att vinna
   mot kvarvarande Bootstrap/Mud/scoped-regler oavsett scope. */
.apl-radio-label {
    color: var(--text) !important;
    font-weight: var(--label-font-weight) !important;
    margin-left: 0.25rem;
    cursor: pointer;
    display: inline-block;
}

    /* Disabled-state — fortfarande synlig men muted, inte 50% opacity. */
    .form-check-input:disabled ~ .apl-radio-label,
    .form-check-input[disabled] ~ .apl-radio-label {
        opacity: 1 !important;
        color: var(--muted) !important;
        cursor: not-allowed;
    }

/* ---- 4. Modal density presets (FE15) ------------------------------- */
/* Fyra storlekar för Blazored.Modal som ersätter handskrivna
   `col-X-12 col-Y-Z`-strängar i ModalOptions.Class. Alla presets
   garanterar full bredd på mobile (xs+sm < 768px) så små-på-desktop-
   modaler inte blir små-på-mobile också. Använd via
   `AplModalOptions.Narrow()/.Medium()/.Wide()/.Fullscreen()` factory
   (se `Helper/AplModalOptions.cs`).

   Storleksval per innehållstyp:
     - Narrow      : confirmation, single-input, "byt skola"-lista
     - Medium      : edit-formulär, person-/företags-detaljer
     - Wide        : multi-section, tabeller, kontrakts-modal
     - Fullscreen  : audit-loggar, dashboards, fullsidor-preview */

.apl-modal-narrow,
.apl-modal-medium,
.apl-modal-wide,
.apl-modal-fullscreen {
    margin-top: 1rem;
    margin-bottom: 1rem;
}

/* Modal-bredder är MOBILE-FIRST + ordnade smallest→largest så cascade
   fungerar: senare media-query vinner vid större viewport, vid mindre
   viewport ärvs den föregående bredare regeln.

   Hög inzoom (200% på 1366 = 683px / på 1920 = 960px) ska INTE göra modaler
   ihoptryckta — i 768-1199px-spannet får de generös bredd (75-95%). På
   `lg+` (≥1200px) är ingen modal full bredd; max ~80% även för wide.

   Layout-baseline 960px synkas med repons FE4-konvention (sidebar/navbar
   skiftar där) så modalerna går till "desktop-presentation" samtidigt som
   layouten själv. */

.apl-modal-narrow {
    width: 100%;
    max-width: 100%;
}

@media (min-width: 576px) {
    .apl-modal-narrow {
        max-width: 92%;
    }
}

@media (min-width: 768px) {
    .apl-modal-narrow {
        max-width: 75%;
    }
}

@media (min-width: 960px) {
    .apl-modal-narrow {
        max-width: 55%;
    }
}

@media (min-width: 1200px) {
    .apl-modal-narrow {
        max-width: 50%;
    }
}

.apl-modal-medium {
    width: 100%;
    max-width: 100%;
}

@media (min-width: 576px) {
    .apl-modal-medium {
        max-width: 96%;
    }
}

@media (min-width: 768px) {
    .apl-modal-medium {
        max-width: 88%;
    }
}

@media (min-width: 960px) {
    .apl-modal-medium {
        max-width: 72%;
    }
}

@media (min-width: 1200px) {
    .apl-modal-medium {
        max-width: 78%;
    }
}

.apl-modal-wide {
    width: 100%;
    max-width: 100%;
}

@media (min-width: 768px) {
    .apl-modal-wide {
        max-width: 96%;
    }
}

@media (min-width: 960px) {
    .apl-modal-wide {
        max-width: 88%;
    }
}

@media (min-width: 1200px) {
    .apl-modal-wide {
        max-width: 90%;
    }
}

.apl-modal-fullscreen {
    width: 100%;
    max-width: 100%;
    min-height: calc(100vh - 4rem);
}

/* ---- 5. Theme-picker shape-toggle active state --------------------- */
/* Globalt eftersom checkbox-state (från det globala #apl-square-toggle
   i MainLayout) styr båda lablarnas highlight via :root:has(). Scoped
   CSS kan inte se ett globalt element. */
:root:has(.apl-square-toggle:checked) .shape-toggle-preview--square,
:root:not(:has(.apl-square-toggle:checked)) .shape-toggle-preview--rounded {
    border-color: var(--saveb-bg);
    background: color-mix(in srgb, var(--saveb-bg) 12%, transparent);
    color: var(--text);
}

/* ---- 6. .apl-file-button ------------------------------------------- */
/* Standard-knapp-styling för file-upload via `<label for="...">`-pattern.
   Native `<input type="file">` döljs (`d-none` / `visually-hidden`) och
   labeln styles som standardknapp. Klick på label triggar input via
   `for=`-koppling. Färg/storlek/radius följer aktivt tema via samma
   variabler som SaveButton/SmallButton. */
.apl-file-button {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: var(--saveb-bg);
    color: var(--saveb-text);
    border: 1px solid var(--saveb-bg);
    padding: 0.5rem 1rem;
    border-radius: var(--button-radius);
    font-size: var(--label-font-size);
    font-weight: 500;
    cursor: pointer;
    user-select: none;
    transition: background 0.15s ease, color 0.15s ease;
}

    .apl-file-button:hover {
        background: var(--saveb-hover-bg);
        color: var(--saveb-hover-text);
    }

    .apl-file-button:focus-within {
        outline: 2px solid var(--text);
        outline-offset: 2px;
    }

/* ---- 7. praxoConfirm modal ---------------------------------------- */
/* Tema-aware ersättning för native window.confirm(). JS-implementation
   i wwwroot/js/site.js skapar `<div id="praxo-confirm-root">` med dessa
   klasser. Färger/radius följer aktivt tema via CSS-variabler. */
#praxo-confirm-root {
    pointer-events: none;
}

.praxo-confirm-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    /* Above Mud/Blazored modals (which sit at ~1060-1300). User-rapport
       2026-05-11: confirm hamnade UNDER Blazor-modaler vid 1090/1095. */
    z-index: var(--z-confirm-backdrop, 100000);
    pointer-events: auto;
    animation: praxo-confirm-fade 0.15s ease;
}

.praxo-confirm-dialog {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: var(--card-bg);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--card-radius);
    padding: 1.5rem;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
    min-width: 320px;
    max-width: calc(100vw - 32px);
    z-index: var(--z-confirm, 100001);
    pointer-events: auto;
    animation: praxo-confirm-slide 0.2s ease;
    font-size: var(--label-font-size);
}

.praxo-confirm-message {
    color: var(--text);
    margin-bottom: 1.25rem;
    line-height: 1.5;
}

.praxo-confirm-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.praxo-confirm-btn {
    padding: 0.5rem 1.25rem;
    border-radius: var(--button-radius);
    cursor: pointer;
    font-weight: 500;
    font-size: var(--label-font-size);
    border: 1px solid var(--border);
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
    min-width: 90px;
}

.praxo-confirm-cancel {
    background: var(--card-bg);
    color: var(--text);
}

.praxo-confirm-cancel:hover {
    background: color-mix(in srgb, var(--text) 8%, var(--card-bg));
    border-color: var(--text);
}

.praxo-confirm-ok {
    background: var(--saveb-bg);
    color: var(--saveb-text);
    border-color: var(--saveb-bg);
}

.praxo-confirm-ok:hover {
    background: var(--saveb-hover-bg);
    color: var(--saveb-hover-text);
    border-color: var(--saveb-hover-bg);
}

.praxo-confirm-btn:focus-visible {
    outline: 2px solid var(--text);
    outline-offset: 2px;
}

@keyframes praxo-confirm-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes praxo-confirm-slide {
    from { opacity: 0; transform: translate(-50%, -45%); }
    to   { opacity: 1; transform: translate(-50%, -50%); }
}

@media (prefers-reduced-motion: reduce) {
    .praxo-confirm-backdrop,
    .praxo-confirm-dialog {
        animation: none !important;
    }
}

/* ---- 6. Page migration utilities (FE-konventions-migration §11, 2026-05-07)
   Klasser som tidigare bodde i sidors scoped CSS (Pages/**/*.razor.css)
   men som per §11 inte får ligga där. Konsoliderade hit för att låta
   sidornas .razor.css raderas. Namnen är `apl-`-prefixade per §6. */

/* Småformat-skol/kommun-logo i tabellrader/kort. Tidigare `.school-logo`
   lokalt i 4 sidors scoped CSS (Period, Schools, Organisations, MySchool)
   med identisk styling.

   `!important` + `max-width` krävs eftersom markup på vissa sidor (Schools,
   Period, Organisations) också har `.img-responsive` som sätter
   `width: 100%; max-width: none` (newlook.css:809). Båda klasser har
   specificity 0,1,0; den scoped CSS-suffix som tidigare gav extra specificity
   är borta efter §11-migration. Utan `!important` kan render-resultatet
   variera (cache, build-state) och bilderna växer till container-bredd. */
.apl-school-logo {
    width: 60px !important;
    max-width: 60px !important;
    height: auto !important;
}

/* Hög-orientation skol-logo — för layouter där logon visas i en smal
   kolumn (t.ex. switch-school-vyn) och höjd är begränsande dimension.
   Tidigare `.school-logo` med transponerad orientation i ChangeSchool.razor.css.
   Samma `!important`-skydd mot `.img-responsive` som `.apl-school-logo` ovan. */
.apl-school-logo-tall {
    height: 50px !important;
    max-height: 50px !important;
    width: auto !important;
}

/* Tjock divider — tema-medveten via `--text`. Tidigare `.audit-divider` i
   AuditLog.razor.css. */
.apl-audit-divider {
    height: 5px;
    background-color: var(--text);
    border: none;
}

/* Bransch-/industri-select med kompakt text för tabell-cell-rendering där
   många optioner ska få plats. Tidigare `.industry-select` i
   CompanyInfo.razor.css. Hardcoded font-size är medvetet — option-element
   skalas inte av FontSizePicker pga native-OS-rendering. */
.apl-industry-select,
.apl-industry-select option {
    font-size: 10px;
}

/* Empty-state placeholder för "inga data"-vyer. Tidigare `.empty-state` i
   AttendanceTeacher.razor.css. */
.apl-empty-state {
    min-height: 40vh;
}

/* Form-action-spacer — extra padding-top under formulärsektion för att
   ge plats åt sticky/floating actions. Tidigare `.action-spacer` i
   AddInternship.razor.css (70px är medvetet specifikt — Bootstrap pt-5
   ger bara 48px). */
.apl-action-spacer {
    padding-top: 70px;
}

/* Journal-textarea — höjd 200px, full bredd, tema-medveten bg/border.
   Tidigare `.journal-textarea` i AddAndEditAttendanceJournalComment.razor.css. */
.apl-journal-textarea {
    width: 100%;
    height: 200px;
    font-size: 1rem;
    background-color: var(--card-bg);
    border: 1px solid var(--border);
}

/* News-content-box — long-form text wrapping för nyhetsartikel-rendering.
   Tidigare `.box` i News.razor.css (generic name, omdöpt för att undvika
   kollision i global scope). */
.apl-news-content {
    inline-size: 100rem;
    overflow-wrap: break-word;
}

/* Slide-toggle-label — sub-label ovanför SlideButton/RadioGroup. Tidigare
   `.slide-label` i CompanyInformation.razor.css. Tema-medveten via
   `var(--muted)`. Används också (ännu duplikat-scoped) i SendMail,
   EditAvailableSpotsModal, AddTutor — kandidater för konsolidering hit
   i framtida batch. */
.apl-slide-label {
    margin-bottom: 5px;
    color: var(--muted);
}

/* Soft success-alert — Bootstrap `.alert.alert-success`-override med mjukare
   pastel-bakgrund och border. Tidigare `.apl-alert-success-soft` (redan
   apl-prefix) lokalt i CompanyInformation.razor.css — tydligt avsedd för
   global. Hardcoded färger är medvetna status-semantik (mjuk grön). */
.apl-alert-success-soft {
    background-color: #e9f7ef;
    border: 1px solid #b8e0c8;
}

/* Editor-wrapper utilities — för layout runt RadzenHtmlEditor/Quill där
   editorn annars blir för bred eller cuttar overflow. Tidigare
   `.editor-shrink-fix` + `.editor-overflow-wrap` i CompanyInformation.razor.css
   (också scoped-duplikat i AddTutor med flera). */
.apl-editor-shrink-fix {
    min-width: 0;
}

.apl-editor-overflow-wrap {
    overflow-x: auto;
    max-width: 100%;
}

/* Brand-save-button — pill-formad submit-knapp som följer tema-systemet
   via `--saveb-*`-variabler (default-tema = jkpng mörk-teal #183c49,
   identisk med original-värde, så ingen visuell regression i default).
   Tidigare `.brand-save-button` i CompanyInformation.razor.css med
   hardcoded färger. Tema-medveten per user-godkännande 2026-05-07. */
.apl-brand-save-button {
    background-color: var(--saveb-bg);
    border-radius: 40px;
    color: var(--saveb-text);
}

    .apl-brand-save-button:hover,
    .apl-brand-save-button:focus {
        background-color: var(--saveb-hover-bg);
        color: var(--saveb-hover-text);
    }

/* Template-row — fix-höjd 400px för 2-koloners-layout med vänster
   beskrivning + höger frågor/innehåll. Tidigare `.template-row` IDENTISK
   i 3 sidor (EducationalMappingTemplates, InternshipAssessmentTemplate,
   RiskTemplates) — triple-duplicate. Konsoliderad hit. */
.apl-template-row {
    height: 400px;
}

/* Scrollable card-body — höjd 300px med vertikal scroll, för card-innehåll
   som kan vara längre än kortet. Tidigare `.scrollable-card-body` IDENTISK
   i samma 3 filer som `.apl-template-row`. */
.apl-scrollable-card-body {
    overflow-y: auto;
    height: 300px;
    -webkit-overflow-scrolling: touch;
}

/* Quill/Radzen WYSIWYG-preview canvas — neutralt vitt papper för rendering
   av sparat MarkupString-innehåll. Inline-färger från sparat innehåll
   (font-color, highlight-bg) bevaras eftersom de har högre specificitet
   via inline style. `!important` krävs för att slå tema-förälderns
   bakgrundsfärg. Används idag på vänster card-body i RiskTemplates.razor
   (.col-lg-4 > .card > .card-body). Tidigare implementerad som
   `.template-row .col-lg-4 > .card > .card-body` i RiskTemplates.razor.css
   — bytt till explicit klass-applicering för tydlighet och flexibilitet. */
.apl-quill-preview-canvas {
    background-color: #ffffff !important;
    color: #1a1a1a !important;
}

/* Mail-form-utilities — tidigare scoped i `Pages/Coordinator/Mail/Mail.razor.css`
   (sida — bröt §11). Bilage-listan + mottagare-räknaren + progress-texten
   används i Mail-komponenten på `/shared/dispatches` och `/coordinator/mail`.
   `#eee` → `var(--border)` för tema-medvetenhet. */
.apl-mail-form .form-label {
    font-weight: 600;
    margin-bottom: 0.25rem;
}

.apl-attachments-container {
    display: flex;
    flex-direction: column;
}

.apl-attachment-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.25rem 0.5rem;
    border-bottom: 1px solid var(--border);
}

    .apl-attachment-row:last-child {
        border-bottom: none;
    }

.apl-attachment-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 85%;
}

.apl-recipient-count {
    font-weight: 600;
    margin-top: 1.8rem;
}

.apl-progress-text {
    font-size: 0.9rem;
    margin-bottom: 0.25rem;
}
