/* ==========================================================================
   Janki Steno — responsive hardening for the public site and student portal
   Loaded after theme.css / style.css in both public and student layouts.
   theme.css already handles the header collapse and the big section
   breakpoints; this file covers the gaps: page-level overflow guards, legacy
   markup (tables, <center> blocks) inherited from the old views, tap-target
   sizing, and the phone end of the typing / steno test pages.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Page-level guards
   -------------------------------------------------------------------------- */

/* `clip`, not `hidden`: overflow-x:hidden turns the root into a scroll
   container and silently kills the sticky site header. `clip` contains a
   stray few pixels without creating one. Browsers too old for `clip` fall
   back to `visible`, which is safe — the audited pages have no real
   horizontal overflow to hide. */
html,
body {
    max-width: 100%;
    overflow-x: clip;
}

/* Media and embeds never dictate the page width. */
img,
svg,
video,
canvas,
iframe,
embed,
object {
    max-width: 100%;
}

img,
video {
    height: auto;
}

/* Long URLs, emails and transaction ids wrap instead of stretching a card. */
p,
li,
dd,
td,
th,
.js-card,
.card-body {
    overflow-wrap: anywhere;
}

/* Pre/code blocks scroll rather than push the layout. */
pre {
    overflow-x: auto;
    max-width: 100%;
}

/* --------------------------------------------------------------------------
   Legacy markup carried over from the old views
   -------------------------------------------------------------------------- */

/* Several student views still wrap tables in <center>. Make those scroll. */
center > table,
.js-main table:not(.tp-bar):not([class*="table-responsive"]) {
    max-width: 100%;
}

center {
    max-width: 100%;
}

/* Any bare <table> inside the app shell gets its own scroll context. */
.js-main .table-scroll,
.js-main .table-responsive,
.js-main .table-responsive-sm {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* --------------------------------------------------------------------------
   Forms and controls
   -------------------------------------------------------------------------- */

@media (max-width: 767.98px) {
    /* iOS zooms the viewport when a focused input is under 16px. */
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
    select,
    textarea {
        font-size: 16px;
    }

    .form-control,
    .form-select {
        min-height: 44px;
    }

    /* Buttons that sit alone in a row read better full width on a phone. */
    .js-form .btn,
    .js-auth-card .btn[type="submit"] {
        width: 100%;
    }
}

/* Comfortable tap targets on touch devices without a hover cursor. */
@media (hover: none) and (pointer: coarse) {
    .btn,
    .js-nav-link,
    .dropdown-item {
        min-height: 42px;
        display: inline-flex;
        align-items: center;
    }

    .dropdown-item {
        display: flex;
    }

    /* Footer links are plain inline text at ~20px tall — well under a
       comfortable thumb target. Pad them without disturbing the text flow. */
    .js-footer-links a,
    .js-footer-legal a,
    .js-contact-row a,
    .js-auth-foot a,
    .js-auth-back {
        display: inline-block;
        padding-block: .35rem;
        min-height: 34px;
    }

    .js-footer-links li {
        margin-bottom: .1rem;
    }
}

/* --------------------------------------------------------------------------
   Public site — sections and footer
   -------------------------------------------------------------------------- */

@media (max-width: 575.98px) {
    .js-footer-grid {
        gap: 1.75rem;
    }

    .js-footer-bottom {
        flex-direction: column;
        align-items: flex-start;
        gap: .6rem;
        text-align: left;
    }

    .js-footer-legal {
        display: flex;
        flex-wrap: wrap;
        gap: .35rem .9rem;
    }

    /* The WhatsApp bubble collapses to just the icon so it does not cover
       half the screen next to the install pill. */
    .js-whatsapp .js-whatsapp-label {
        display: none;
    }
}

/* The install pill and the WhatsApp bubble are fixed to the bottom corners.
   Reserve room so they never sit permanently on top of the last line of the
   page (the footer legal links in particular). */
@media (max-width: 991.98px) {
    .js-footer-bottom,
    .js-appfooter-inner {
        padding-bottom: 3.5rem;
    }
}

/* --------------------------------------------------------------------------
   Student portal — app footer
   -------------------------------------------------------------------------- */

@media (max-width: 767.98px) {
    .js-appfooter-inner {
        flex-direction: column;
        align-items: center;
        gap: .35rem;
        text-align: center;
        font-size: .78rem;
        line-height: 1.6;
    }
}

/* --------------------------------------------------------------------------
   Typing / steno test pages — phone end
   test-page.css stops at 900px; below that the toolbar needs to become a
   two-column grid and the timer has to stop competing with the controls.
   -------------------------------------------------------------------------- */

@media (max-width: 600px) {
    .tp-stage {
        padding: .75rem .6rem 1.25rem;
    }

    .tp-bar {
        padding: .8rem .85rem;
        gap: .7rem .85rem;
    }

    .tp-id {
        flex-basis: 100%;
        order: -2;
    }

    .tp-title {
        font-size: .98rem;
        white-space: normal;
    }

    /* Two controls per row keeps labels readable at 360px. */
    .tp-ctl {
        flex: 1 1 calc(50% - .5rem);
        min-width: 0;
    }

        .tp-ctl .tp-select,
        .tp-ctl .tp-num {
            width: 100%;
            min-width: 0;
        }

    .tp-start {
        width: 100%;
    }

    .tp-ctl:has(.tp-start) {
        flex-basis: 100%;
    }

    /* Timer to its own full-width row, above the controls. */
    .tp-timer {
        order: -1;
        flex-basis: 100%;
        margin-left: 0;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: .75rem;
    }

    .base-timer {
        width: 74px;
        height: 74px;
    }

    .tp-pane-head {
        flex-wrap: wrap;
        gap: .35rem .75rem;
    }

    .tp-pane-hint {
        flex-basis: 100%;
        font-size: .72rem;
    }

    .tp-read {
        max-height: 45vh;
        overflow-y: auto;
    }

    .tp-write textarea {
        font-size: 1.05rem;
        min-height: 12rem;
    }

    .tp-actions {
        flex-direction: column;
        align-items: stretch;
        gap: .6rem;
    }

    .tp-submit {
        width: 100%;
    }

    .tp-steps {
        font-size: .85rem;
    }
}

/* Small phones (360px and under): one control per row — two columns can no
   longer hold a select plus its label without spilling out of the bar. */
@media (max-width: 380px) {
    .tp-stage {
        padding-inline: .45rem;
    }

    .tp-bar {
        padding: .7rem .6rem;
    }

    .tp-ctl {
        flex-basis: 100%;
    }

    .tp-ctl-body {
        flex-wrap: wrap;
    }

    .tp-num,
    .tp-select {
        flex: 1 1 auto;
        min-width: 0;
    }

    .tp-tag {
        font-size: .64rem;
    }
}

/* A real keyboard is required for these pages — say so rather than letting
   someone start a timed test they cannot finish. */
.tp-touch-note {
    display: none;
    margin: 0 0 .75rem;
    padding: .7rem .9rem;
    border-radius: .65rem;
    background: rgba(240, 160, 32, .14);
    border: 1px solid rgba(240, 160, 32, .38);
    color: #ffd89a;
    font-size: .82rem;
    line-height: 1.55;
}

@media (hover: none) and (pointer: coarse) {
    .tp-touch-note {
        display: block;
    }
}

/* --------------------------------------------------------------------------
   Auth cards (login / register / reset)
   .js-auth-card is a grid item, so it inherits min-width:auto and cannot
   shrink below its content's min-content width — on a 320px screen that
   pushed the card ~2px wider than the viewport.
   -------------------------------------------------------------------------- */

.js-auth-card,
.js-auth-card > *,
.js-auth-form,
.js-auth-aside {
    min-width: 0;
}

@media (max-width: 359.98px) {
    .js-auth {
        padding-inline: .5rem;
    }

    .js-auth-form,
    .js-auth-aside {
        padding-inline: 1rem;
    }
}

/* --------------------------------------------------------------------------
   Package grid
   Grid items default to min-width:auto, so a card whose content has a wide
   min-content size pushes the track past its minmax() floor and the grid
   overflows on narrow phones.
   -------------------------------------------------------------------------- */

.js-pkg-grid {
    grid-template-columns: repeat(auto-fill, minmax(min(248px, 100%), 1fr));
}

    .js-pkg-grid > * {
        min-width: 0;
    }

.js-pkg {
    min-width: 0;
}

    .js-pkg .js-pkg-title,
    .js-pkg h3,
    .js-pkg h4 {
        overflow-wrap: anywhere;
    }

/* Any other auto-fill grid in the app gets the same guard. */
[class*="-grid"] > * {
    min-width: 0;
}

/* --------------------------------------------------------------------------
   Results / dashboard cards
   -------------------------------------------------------------------------- */

@media (max-width: 767.98px) {
    /* The results view lays stats out with .col-md-3 paragraphs; on a phone
       they stack, so tighten the rhythm. */
    .js-main .col-md-3 p,
    .js-main p.col-md-3,
    .js-main p.col-md-4 {
        margin-bottom: .35rem;
        font-size: .88rem;
    }

    .js-main .table td,
    .js-main .table th {
        white-space: nowrap;
        font-size: .85rem;
    }
}

/* --------------------------------------------------------------------------
   Print
   -------------------------------------------------------------------------- */

@media print {
    .js-header,
    .js-footer,
    .js-appfooter,
    .js-whatsapp {
        display: none !important;
    }

    body {
        overflow: visible;
    }
}
