/* CompTIA Security+ SY0-701 Practice - Main Styles */

:root {
    --primary-color: #0d6efd;
    --success-color: #198754;
    --danger-color: #dc3545;
    --warning-color: #ffc107;
    --info-color: #0dcaf0;

    /* Per-test-type accent colours (defaults to primary) */
    --test-accent:       #0d6efd;
    --test-accent-light: #e7f1ff;
    --test-accent-dark:  #0a58ca;
}

/* ── Global 20 % size reduction ── */
h1 { font-size: 1.6rem !important; }
h2 { font-size: 1.3rem !important; }
h3 { font-size: 1.1rem !important; }
h4 { font-size: 1rem   !important; }
h5 { font-size: 0.9rem !important; }
h6 { font-size: 0.82rem !important; }

.card-body       { padding: 0.9rem !important; }
.card-header     { padding: 0.6rem 0.9rem !important; }
.btn             { font-size: 0.85rem !important; padding: 0.35rem 0.75rem !important; }
.btn-sm          { font-size: 0.78rem !important; padding: 0.25rem 0.55rem !important; }
.form-label      { font-size: 0.85rem !important; margin-bottom: 0.3rem !important; }
.form-control,
.form-select     { font-size: 0.85rem !important; padding: 0.3rem 0.6rem !important; }
.form-text       { font-size: 0.75rem !important; }
.alert           { font-size: 0.82rem !important; padding: 0.5rem 0.8rem !important; }
.badge           { font-size: 0.72rem !important; }
p                { margin-bottom: 0.4rem; font-size: 0.88rem; }
small            { font-size: 0.72rem !important; }
.text-muted      { font-size: 0.8rem; }
.container       { padding-top: 0.6rem; }

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

#app {
    flex: 1;
    display: flex;
    flex-direction: column;
}

main {
    flex: 1;
}

/* Authentication Pages */
.auth-container {
    max-width: 400px;
    margin: 36px auto;
}

.auth-card {
    box-shadow: 0 0.4rem 0.8rem rgba(0, 0, 0, 0.13);
    border-radius: 0.5rem;
}

/* Dashboard */
.stats-card {
    transition: transform 0.2s;
}

.stats-card:hover {
    transform: translateY(-4px);
}

.stats-card i {
    font-size: 2rem;
}

/* Test Interface */
.test-container {
    /* Expressed as a base and a multiplier so the wide mode below is a
       proportion of this rather than a second number to keep in step. Change
       the base and both widths follow. */
    --test-width-base:  860px;
    --test-width-scale: 1;

    max-width: calc(var(--test-width-base) * var(--test-width-scale));
    margin: 0 auto;
}

/* Per-test-type colour themes */
.test-theme-daily {
    --test-accent:       #d97706;
    --test-accent-light: #fef3c7;
    --test-accent-dark:  #b45309;
}
.test-theme-section {
    --test-accent:       #0891b2;
    --test-accent-light: #cffafe;
    --test-accent-dark:  #0e7490;
}
.test-theme-full_exam {
    --test-accent:       #4f46e5;
    --test-accent-light: #ede9fe;
    --test-accent-dark:  #4338ca;
}
.test-theme-retry {
    --test-accent:       #dc2626;
    --test-accent-light: #fee2e2;
    --test-accent-dark:  #b91c1c;
}

/* Themed header card */
.test-header-card {
    border-top: 3px solid var(--test-accent) !important;
}

/* Themed progress bar */
.test-progress .progress-bar {
    background-color: var(--test-accent) !important;
}

/* Themed question nav current button */
.question-nav-btn.current {
    background-color: var(--test-accent) !important;
    border-color:     var(--test-accent) !important;
    color: white !important;
}

/* Themed question card */
.question-card {
    border: 2px solid #dee2e6;
    border-radius: 0.5rem;
    transition: border-color 0.3s;
}

.question-card.answered {
    border-color: var(--success-color);
}

.option-button {
    width: 100%;
    text-align: left;
    padding: 0.65rem 0.85rem;
    margin-bottom: 0.5rem;
    border: 2px solid #dee2e6;
    background: white;
    transition: all 0.2s;
    font-size: 0.875rem;
}

.option-button:hover {
    border-color: var(--test-accent);
    background: var(--test-accent-light);
}

.option-button.selected {
    border-color: var(--test-accent);
    background: var(--test-accent-light);
    font-weight: 500;
}

.option-button.correct {
    border-color: var(--success-color);
    background: #d1e7dd;
}

.option-button.incorrect {
    border-color: var(--danger-color);
    background: #f8d7da;
}

.option-button.disabled {
    cursor: not-allowed;
    opacity: 0.6;
}

/* Timer */
.timer {
    font-size: 1.2rem;
    font-weight: bold;
}

.timer.warning {
    color: var(--warning-color);
    animation: pulse 1s infinite;
}

.timer.danger {
    color: var(--danger-color);
    animation: pulse 0.5s infinite;
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.6; }
}

/* Question Navigation */
.question-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.question-nav-btn {
    width: 32px;
    height: 32px;
    border: 1px solid #dee2e6;
    background: white;
    border-radius: 0.25rem;
    font-size: 0.75rem;
    transition: all 0.2s;
}

.question-nav-btn:hover {
    background: #f8f9fa;
}

.question-nav-btn.answered {
    background: var(--success-color);
    color: white;
    border-color: var(--success-color);
}

/* ── Wiki Styles ── */
.wiki-page {
    background: #fff;
    /* Break out of main container-fluid py-4: all of its top padding and 12px
       of each side. Named because the phone tables below measure from it. */
    --wiki-page-bleed: 12px;
    margin: -1.5rem calc(-1 * var(--wiki-page-bleed)) 0 calc(-1 * var(--wiki-page-bleed));
}

.wiki-header {
    background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%) !important;
}

.wiki-domain-nav .nav-link {
    font-size: 0.82rem;
    color: #495057;
    border-bottom: 3px solid transparent !important;
    border-radius: 0 !important;
    padding: 0.6rem 1rem !important;
    white-space: nowrap;
}

.wiki-domain-nav .nav-link.active {
    color: #0d6efd !important;
    border-bottom-color: #0d6efd !important;
    background: transparent;
    font-weight: 600;
}

.wiki-domain-nav .nav-link:hover:not(.active) {
    color: #0d6efd;
    background: rgba(13,110,253,0.05);
}

.wiki-sidebar {
    border-right: 1px solid #dee2e6;
}

.wiki-sidebar .nav-link {
    font-size: 0.82rem !important;
    color: #495057 !important;
    padding: 0.4rem 0.75rem !important;
    transition: background 0.15s, color 0.15s;
}

.wiki-sidebar .nav-link:hover {
    background: rgba(13,110,253,0.08);
    color: #0d6efd !important;
}

.wiki-sidebar .nav-link.active {
    background: rgba(13,110,253,0.1);
    color: #0d6efd !important;
    font-weight: 600;
}

.wiki-topic-body h4 {
    font-size: 1rem !important;
    font-weight: 700;
    margin-top: 1.5rem;
    margin-bottom: 0.6rem;
    color: #1a1a2e;
    padding-bottom: 0.3rem;
    border-bottom: 2px solid #e9ecef;
}

.wiki-topic-body h4:first-child {
    margin-top: 0;
}

.wiki-topic-body p {
    font-size: 0.875rem !important;
    line-height: 1.65;
    color: #333;
}

.wiki-topic-body ul,
.wiki-topic-body ol {
    font-size: 0.875rem;
    padding-left: 1.5rem;
}

.wiki-topic-body li {
    margin-bottom: 0.3rem;
    line-height: 1.55;
}

.wiki-topic-body table {
    font-size: 0.8rem !important;
}

.wiki-topic-body code {
    font-size: 0.8rem;
    background: #f8f9fa;
    padding: 0.1rem 0.3rem;
    border-radius: 3px;
    color: #d63384;
}

.wiki-topic-body .alert {
    font-size: 0.82rem !important;
}

.wiki-topic-body dt {
    font-weight: 700;
    color: #1a1a2e;
    font-size: 0.88rem;
    margin-top: 0.8rem;
}

.wiki-topic-body dd {
    font-size: 0.83rem;
    color: #444;
    margin-left: 1rem;
    margin-bottom: 0.5rem;
}

.wiki-topic-card {
    transition: transform 0.15s, box-shadow 0.15s;
    border: 1px solid #dee2e6;
}

.wiki-topic-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0,0,0,0.1) !important;
    border-color: #0d6efd;
}

/* ---------------------------------------------------------------------------
   The study wiki on phones.

   Below 768px the sidebar stacks above the topic, and the topic sat inside
   three paddings: the page gutter, the row's container, and the pane's own
   p-4. Measured at 412px, the width of a Pixel 6 Pro, that left 292px for
   tables of three to five columns. 42 of the 80 tables ran past the column's
   right edge, and in six topics the page itself became wider than the screen,
   which is what made Android shrink the whole view. At 360px it was 61 tables
   and seventeen topics.

   Three widths now, each for a reason:
   - Text: the pane drops its side padding below md (px-0 px-md-4 in
     Wiki.js), so it lines up with the menu above it.
   - Tables go further, out to the edges of the dark header, because they
     carry the most per line. One that still does not fit scrolls inside its
     own box instead of pushing the page sideways.
   - The boxes that exist to stand out - exam tips, worked examples, the card
     grids - get the removed padding back as margin, so they keep exactly the
     width they had. Now narrower than the text around them, they read as
     asides rather than as more of the same column.

   Every distance the tables use is derived from the rules that create it -
   --page-gutter-* on .container-fluid, --wiki-page-bleed on .wiki-page -
   rather than restated here, because a restated copy is how .wiki-page's own
   -12px went stale once already. The boxes' 1.5rem is the padding px-md-4
   keeps above this breakpoint. Tablet and desktop are untouched: every rule
   that moves anything is inside the query, the two outside it only give
   names to values that were already there, and .wiki-table is an unstyled
   block. Measured, not assumed - 550 values each at 768px and 1280px, before
   and after, all identical.
   --------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    /* How far .wiki-page sits in from the screen: main's gutter, less what
       .wiki-page takes back. Worked out here, where var(--page-gutter-*) is
       still main's; the topic's own container redefines it further in. */
    .wiki-page {
        --wiki-inset-left:  calc(var(--page-gutter-left)  - var(--wiki-page-bleed));
        --wiki-inset-right: calc(var(--page-gutter-right) - var(--wiki-page-bleed));
    }

    /* The box spans the whole screen - out through the topic's container and
       the page's inset - and its padding brings a table that fits back into
       line with the dark header. A table slightly too wide spills into that
       padding and is still seen whole; a much wider one is cut at the edge
       of the screen rather than short of it, which reads as more to swipe to
       instead of as something clipped. */
    .wiki-topic-body > .wiki-table {
        margin-left:   calc(-1 * (var(--page-gutter-left)  + var(--wiki-inset-left)));
        margin-right:  calc(-1 * (var(--page-gutter-right) + var(--wiki-inset-right)));
        padding-left:  var(--wiki-inset-left);
        padding-right: var(--wiki-inset-right);
        overflow-x: auto;
    }

    /* Code has no natural break points, so one long line of it sets the width
       of its whole column: the XSS example in 2.3 made that table 511px and
       crushed the other columns to a word per line. Breaking code anywhere
       is normal on a narrow screen; breaking prose is not, so this stays on
       code. */
    .wiki-topic-body td code,
    .wiki-topic-body th code {
        overflow-wrap: anywhere;
    }

    .wiki-topic-body > .alert,
    .wiki-topic-body > .card {
        margin-left:  1.5rem;
        margin-right: 1.5rem;
    }

    /* A row's own negative margin, half its gutter, is kept inside the inset
       so its cards line up with the boxes above and below them. */
    .wiki-topic-body > .row {
        margin-left:  calc(1.5rem - 0.5 * var(--bs-gutter-x));
        margin-right: calc(1.5rem - 0.5 * var(--bs-gutter-x));
    }
}

/* Progress Bar */
.progress-custom {
    height: 22px;
    font-size: 0.8rem;
    font-weight: 500;
}

/* Results */
.score-display {
    font-size: 3.2rem;
    font-weight: bold;
}

.score-display.passed {
    color: var(--success-color);
}

.score-display.failed {
    color: var(--danger-color);
}

.domain-breakdown {
    margin: 1.2rem 0;
}

.domain-bar {
    margin-bottom: 1rem;
}

.domain-bar .progress {
    height: 20px;
}

/* Weakness Analysis */
.weakness-card {
    border-left: 4px solid;
    margin-bottom: 1rem;
}

.weakness-card.critical {
    border-left-color: var(--danger-color);
}

.weakness-card.needs-improvement {
    border-left-color: var(--warning-color);
}

.weakness-card.good {
    border-left-color: var(--info-color);
}

.weakness-card.strong {
    border-left-color: var(--success-color);
}

/* Profile */
.profile-header {
    background: linear-gradient(135deg, var(--primary-color) 0%, #0a58ca 100%);
    color: white;
    padding: 1.25rem 1.5rem;
    border-radius: 0.5rem;
    margin-bottom: 1.25rem;
}

.streak-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.75rem;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 2rem;
    font-size: 1rem;
}

/* Badges */
.difficulty-badge {
    font-size: 0.75rem;
    padding: 0.25rem 0.5rem;
    border-radius: 0.25rem;
}

.difficulty-easy {
    background: var(--success-color);
    color: white;
}

.difficulty-medium {
    background: var(--warning-color);
    color: #000;
}

.difficulty-hard {
    background: var(--danger-color);
    color: white;
}

/* Loading State */
.loading-spinner {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 220px;
}

/* Responsive */
@media (max-width: 768px) {
    .stats-card {
        margin-bottom: 1rem;
    }

    .score-display {
        font-size: 3rem;
    }

    .question-nav-btn {
        width: 35px;
        height: 35px;
        font-size: 0.75rem;
    }
}

/* Animations */
.fade-enter-active, .fade-leave-active {
    transition: opacity 0.3s;
}

.fade-enter-from, .fade-leave-to {
    opacity: 0;
}

.slide-enter-active, .slide-leave-active {
    transition: transform 0.3s;
}

.slide-enter-from {
    transform: translateX(-100%);
}

.slide-leave-to {
    transform: translateX(100%);
}

/* ─── PBQ Question Types ─── */

.pbq-card {
    border-color: var(--warning-color);
}

.pbq-container {
    padding: 0.5rem 0;
}

/* Drag & Drop */
.drag-item {
    display: inline-flex;
    align-items: center;
    padding: 0.4rem 0.75rem;
    margin-bottom: 0.5rem;
    background: var(--primary-color);
    color: white;
    border-radius: 0.375rem;
    font-size: 0.875rem;
    cursor: grab;
    user-select: none;
    width: 100%;
}

.drag-item:active {
    cursor: grabbing;
}

.drag-item.placed {
    width: auto;
    cursor: default;
}

.drop-target {
    min-height: 52px;
    transition: border-color 0.2s;
}

.drop-target-empty {
    border: 2px dashed #adb5bd !important;
}

.drop-target:hover {
    border-color: var(--primary-color) !important;
}

.drop-zone {
    min-width: 120px;
    text-align: right;
}

/* Items that can still be moved take the gesture for themselves. Without
   touch-action: none a finger on an item scrolls the page and the browser
   cancels the pointer, so the drag never starts - which is exactly how it
   failed on a real phone. Keyed on draggable="true" so placed items, and the
   whole question once it is being reviewed, keep ordinary scrolling. */
.drag-item[draggable="true"] {
    touch-action: none;
    -webkit-touch-callout: none;
}

/* Tapped, and waiting for a target to be tapped. */
.drag-item-selected {
    outline: 3px solid var(--warning-color);
    outline-offset: 2px;
}

/* The original, left behind while its copy travels under the finger. */
.drag-item-lifted {
    opacity: 0.35;
}

/* The copy under the finger: fixed to the viewport, moved by transform from
   QuestionCard.js, and pointer-events: none so it never hides the target
   beneath it from elementFromPoint. */
.drag-ghost {
    position: fixed;
    left: 0;
    top: 0;
    z-index: 2000;
    margin: 0;
    pointer-events: none;
    opacity: 0.95;
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.3);
}

/* The target a dragging finger is over. */
.drop-target.drop-target-hover {
    border: 2px solid var(--primary-color) !important;
    background: var(--test-accent-light);
}

/* An item has been tapped, so every target is now something to tap. */
.drop-target-armed {
    cursor: pointer;
}

.drop-target-armed.drop-target-empty {
    border-color: var(--primary-color) !important;
}

/* The tap hint is for screens with no mouse to drag with. Its display is set
   here rather than with Bootstrap's d-block, whose !important would beat the
   rule that hides it - which is what the first attempt did on a desktop. */
.dnd-touch-hint {
    display: block;
}

@media (hover: hover) and (pointer: fine) {
    .dnd-touch-hint {
        display: none;
    }
}

/* Terminal */
.terminal-window {
    border-radius: 0.5rem;
    overflow: hidden;
    box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}

.terminal-titlebar {
    background: #3a3a3a;
    padding: 0.5rem 0.75rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.terminal-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    display: inline-block;
}

.terminal-body {
    background: #1e1e1e;
    color: #d4d4d4;
    padding: 1rem;
    font-family: 'Cascadia Code', 'Fira Code', 'Courier New', monospace;
    font-size: 0.875rem;
    min-height: 140px;
}

.terminal-context {
    color: #ffd700;
    font-size: 0.8rem;
    border-left: 3px solid #ffd700;
    padding-left: 0.5rem;
}

.terminal-output {
    color: #9cdcfe;
    white-space: pre-wrap;
    font-size: 0.8rem;
    margin-bottom: 0.5rem;
}

.terminal-prompt {
    color: #4ec9b0;
    white-space: nowrap;
    flex-shrink: 0;
}

.terminal-input {
    background: transparent;
    border: none;
    color: #d4d4d4;
    font-family: inherit;
    font-size: inherit;
    flex-grow: 1;
    outline: none;
    caret-color: #d4d4d4;
}

.terminal-input::placeholder {
    color: #555;
}

.terminal-input-display {
    color: #d4d4d4;
    font-family: inherit;
}

/* Utility Classes */
.cursor-pointer {
    cursor: pointer;
}

.text-shadow {
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
}

.card-hover {
    transition: box-shadow 0.3s;
}

.card-hover:hover {
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}

/* Locked-section dialog on the test setup screen.
   z-index sits above Bootstrap's sticky-top (1020) and its own modal layer
   (1055), so the navigation bar cannot overlap the dialog asking permission
   to use it. */
.lock-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1060;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(0, 0, 0, .5);
    animation: lock-modal-fade .15s ease-out;
}

.lock-modal-card {
    width: 100%;
    max-width: 26rem;
    /* Never taller than the screen: the resend message and the throttle
       response both add lines after the dialog is already open. */
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    animation: lock-modal-rise .15s ease-out;
}

@keyframes lock-modal-fade {
    from { opacity: 0; }
}

@keyframes lock-modal-rise {
    from { opacity: 0; transform: translateY(.75rem); }
}

/* Respect a system-level request for reduced motion. */
@media (prefers-reduced-motion: reduce) {
    .lock-modal-backdrop,
    .lock-modal-card { animation: none; }
}

/* Scenario context box on a question.
   The compact-UI block near the top of this file sets .alert to 0.82rem, and
   the text inside used Bootstrap's .small on top of that, which is 0.875em —
   relative, so it compounded and landed at roughly 11px against 13.6px for the
   answer buttons. A scenario is several sentences of the thing being asked
   about, so it was the smallest text on screen while being the most read.
   Matched to .btn, which is what the answer options resolve to. */
.scenario-block .scenario-text {
    font-size: 0.85rem !important;
    line-height: 1.55;
}

/* Wider reading width for the test screen, chosen by the reader.
   A 20% increase on the compact width, not a jump to full screen. The first
   attempt at this went to 1400px and overshot: prose past roughly 90
   characters a line loses the reader on the return sweep to the left margin,
   and the explanations here run to 250 words. 20% is enough to uncramp the
   configuration panels and drag-and-drop targets without reaching that point.
   Only from lg upward: below it the container is already narrower than the
   viewport, so this would change nothing and the toggle is hidden. */
@media (min-width: 992px) {
    .test-container.test-container-wide {
        --test-width-scale: 1.2;
    }
}

/* ---------------------------------------------------------------------------
   Safe areas, for the Android app.
   
   targetSdkVersion 36 means Android enforces edge-to-edge and the app cannot
   opt out, so the WebView draws underneath the status bar. Without this the
   navigation bar sits on top of the clock and battery icons, and the brand
   link is partly unreachable because the system consumes the taps.
   
   This affects every device on Android 15 and later, not only phones with
   curved screens — the curve just makes it more obvious.
   
   env() resolves to 0 wherever there is no inset, so the desktop and the web
   PWA are unaffected. It needs viewport-fit=cover in the viewport meta tag,
   which index.html already has.
   --------------------------------------------------------------------------- */
.navbar {
    padding-top: calc(0.5rem + env(safe-area-inset-top, 0px));
}

/* Gesture navigation overlays the bottom edge the same way. */
footer {
    padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px)) !important;
}

/* Side insets matter on landscape and on curved screens, where the very edge
   of the display is physically hard to touch. */
.container-fluid {
    /* Named so that anything which has to reach the container's edges - the
       wiki's tables on phones - can use the real value rather than a copy of
       it that goes stale when this changes. Custom properties inherit with
       var() already resolved, so descendants get this container's figure. */
    --page-gutter-left:  calc(var(--bs-gutter-x, 0.75rem) + env(safe-area-inset-left, 0px));
    --page-gutter-right: calc(var(--bs-gutter-x, 0.75rem) + env(safe-area-inset-right, 0px));
    padding-left:  var(--page-gutter-left);
    padding-right: var(--page-gutter-right);
}

/* Test history rows open their result on tap, so they need to look tappable. */
.history-row {
    cursor: pointer;
}

/* ---------------------------------------------------------------------------
   The app mark, wherever it appears inside the interface.

   An <img> of a real icon file rather than an icon-font glyph. The glyph was
   only ever a stand-in that happened to resemble the icon, and when the icon
   changed to a monogram the two stopped matching without anything failing.

   No rounding and no ring, because what these <img>s point at is no longer the
   square tile. The tile belongs to the launcher, which crops it to its own
   shape and needs pixels to the edge; used in the interface it landed as a
   blue block on the white login card and vanished entirely against the blue
   navbar. These point at mark-on-light.png and mark-on-dark.png instead — the
   same shield with no ground behind it, coloured for what it sits on. A corner
   radius on a shape that has no corners would only clip its shoulders.
   --------------------------------------------------------------------------- */
.app-mark {
    /* An icon is a picture, not text: never let it stretch with the row. */
    object-fit: contain;
    flex-shrink: 0;
}
