/* PythonMastery — feedback modal.
 *
 * Single source of truth, loaded by every page that offers feedback: the IDE,
 * the academy and its lessons, Tutorial Lab, privacy and terms. It used to live
 * inside styles.css, which the academy build does not load, so feedback could
 * only exist on the pages that happened to share that stylesheet.
 *
 * Written against --accent-primary / --border-main / --text-primary /
 * --text-secondary. The academy stylesheet aliases those onto its own tokens,
 * the same way styles.css aliases the academy's names for the shared theme FAB.
 */

.feedback-trigger-inline {
    background: var(--accent-fill);
    color: white;
    padding: 6px 16px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
    border: none;
    box-shadow: 0 4px 0 rgba(0, 0, 0, 0.2), 0 8px 15px rgba(0, 0, 0, 0.1);
    transform: translateY(0);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

.feedback-trigger-inline:hover {
    filter: brightness(1.1);
    transform: translateY(-2px);
    box-shadow: 0 6px 0 rgba(0, 0, 0, 0.2), 0 12px 20px rgba(0, 0, 0, 0.15);
}

.feedback-trigger-inline:active {
    transform: translateY(2px);
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2), 0 4px 10px rgba(0, 0, 0, 0.1);
}

.feedback-trigger-inline .feedback-icon {
    font-size: 16px;
}

.feedback-modal {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(4px);
    transition: all 0.3s ease;
    overflow-y: auto;
    overscroll-behavior: contain;
    touch-action: none;
    padding: 16px;
}

.feedback-modal.hidden {
    display: none;
    opacity: 0;
    pointer-events: none;
}

.feedback-modal.closing {
    opacity: 0;
    transition: opacity 0.25s ease;
    pointer-events: none;
}

/* The card's entrance. This lived in styles.css, which only the IDE landing and
   Tutorial Lab load, while the rule that uses it sits in this file -- which
   every page loads. A missing @keyframes is not an error: the name resolves to
   nothing and the element just appears. So the modal squashed and settled on
   two pages and blinked into existence on the other nine. Defined here, beside
   its only user. */
@keyframes jelly-open {
    0% {
        transform: scale(0.3, 0.3);
        opacity: 0;
    }

    30% {
        transform: scale(1.1, 0.7);
        /* Stretch horizontal */
    }

    50% {
        transform: scale(0.8, 1.1);
        /* Stretch vertical */
    }

    70% {
        transform: scale(1.05, 0.95);
    }

    100% {
        transform: scale(1, 1);
        opacity: 1;
    }
}

/* The card inherited its type from the page behind it: 16px/24px on the IDE
   landing, 15.5px/24.8px on an academy page, because the two builds set
   different body sizes. Every rem inside the modal then resolved the same but
   every inherited size did not, which is why the same card stood 643px tall on
   one page and 694px on the other. It sets its own type now.

   The h3 and p margins go with it: styles.css resets them globally and
   academy-build.css does not, so the heading started 24px lower on nine pages
   out of eleven. */
.feedback-modal {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 16px;
    line-height: 1.5;
}

.feedback-glass-card h3,
.feedback-glass-card p {
    margin-top: 0;
}

.feedback-glass-card {
    color: var(--text-primary);
    background: rgba(30, 41, 59, 0.7);
    /* Deep Slate */
    backdrop-filter: blur(15px);
    -webkit-backdrop-filter: blur(15px);
    border: 1px solid var(--accent-primary);
    border-radius: 20px;
    width: 100%;
    max-width: 450px;
    padding: 2.5rem;
    position: relative;
    margin: auto;
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
    animation: jelly-open 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
    transition: transform 0.25s ease, opacity 0.25s ease;
    touch-action: pan-y;
    overscroll-behavior: contain;
}

@media (max-height: 600px) {
.feedback-glass-card {
        padding: 1.25rem 1.5rem;
        border-radius: 14px;
    }

    .feedback-field {
        margin-bottom: 0.75rem;
    }

    .feedback-field textarea {
        height: 70px;
    }

    .feedback-title {
        font-size: 1.2rem;
        margin-bottom: 0.25rem;
    }

    .feedback-subtitle {
        margin-bottom: 1rem;
    }
}

.feedback-modal.closing .feedback-glass-card {
    transform: scale(0.95);
    opacity: 0;
    transition: transform 0.25s ease, opacity 0.25s ease;
}

.feedback-close-btn {
    /* The x is a glyph, so it has to be set in the card's own face: left to the
       user agent it came out in Arial on nine page types and Inter on two. */
    padding: 0;
    font-family: inherit;
    line-height: 1;
    position: absolute;
    top: 15px;
    right: 20px;
    font-size: 24px;
    color: var(--text-secondary);
    background: none;
    border: none;
    cursor: pointer;
    transition: color 0.2s ease;
}

.feedback-close-btn:hover {
    color: var(--text-primary);
}

.feedback-title {
    font-size: 1.5rem;
    font-weight: 700;
    margin-bottom: 0.5rem;
    background: linear-gradient(to right, #60a5fa, #a78bfa);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

.feedback-subtitle {
    font-size: 0.9rem;
    color: var(--text-secondary);
    margin-bottom: 2rem;
}

#feedback-form-container.submitting {
    opacity: 0.5;
    pointer-events: none;
    transition: opacity 0.3s ease;
}

.feedback-field {
    margin-bottom: 1.25rem;
}

.feedback-field label {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-secondary);
    margin-bottom: 0.5rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.feedback-field input,
.feedback-field select,
.feedback-field textarea {
    line-height: 1.35;
    width: 100%;
    background: rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    padding: 10px 14px;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.9rem;
    transition: all 0.3s ease;
    outline: none;
}

.feedback-field input:focus,
.feedback-field select:focus,
.feedback-field textarea:focus {
    border-color: var(--accent-primary);
    box-shadow: 0 0 15px rgba(56, 189, 248, 0.3);
    background: rgba(0, 0, 0, 0.3);
}

.feedback-field input::placeholder,
.feedback-field textarea::placeholder {
    color: var(--text-secondary);
    opacity: 0.7;
}

.feedback-field input:focus::placeholder,
.feedback-field textarea:focus::placeholder {
    opacity: 0.4;
}

.feedback-field textarea {
    height: 100px;
    resize: none;
}

.feedback-field .required {
    color: #ef4444;
}

/* Shown only in contact mode, where the form asks for an address and therefore
   owes the reader a sentence about what happens to it. */
.feedback-note {
    margin: -2px 0 14px;
    font-size: 0.78rem;
    line-height: 1.5;
    /* Not opacity. Faded body text measured 4.60:1 on the light card and 4.49:1
       on the cream one -- under the 4.5:1 floor for 12px text, and the reason is
       that opacity flattens the ink towards whatever is behind it. The muted
       colour each theme already defines is the thing to use, and the eye-saver
       card has had its own tuned value since the field text hit 4.31:1. */
    color: var(--text-secondary);
}

/* Self-contained on purpose. This used to be `class="btn-3d feedback-submit-btn"`
   leaning on .btn-3d for its whole appearance -- and .btn-3d lives in
   styles.css, which only the IDE landing and Tutorial Lab load. On every other
   page the reader got a 2px outset Arial button from 1996 sitting under a glass
   card. Everything the button needs to look like itself is now here. */
.feedback-submit-btn {
    width: 100%;
    margin-top: 1rem;
    padding: 12px !important;
    background: var(--accent-fill) !important;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border: none;
    border-radius: 8px;
    color: #fff;
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
    cursor: pointer;
    position: relative;
    top: 0;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    box-shadow: 0 4px 0 rgba(0, 0, 0, 0.2), 0 8px 15px rgba(0, 0, 0, 0.1);
    transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}

.feedback-submit-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 5px 0 rgba(0, 0, 0, 0.2), 0 10px 18px rgba(0, 0, 0, 0.14);
    filter: brightness(1.06);
}

.feedback-submit-btn:active {
    transform: translateY(2px);
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.1);
    filter: none;
}

.feedback-submit-btn .btn-text {
    color: inherit;
    font: inherit;
}

.feedback-error-msg {
    background: rgba(239, 68, 68, 0.12);
    border: 1px solid rgba(239, 68, 68, 0.4);
    color: #f87171;
    border-radius: 8px;
    padding: 10px 14px;
    font-size: 0.85rem;
    margin-top: 0.75rem;
    line-height: 1.5;
}

/* Success State Styles */
#feedback-success {
    text-align: center;
    padding: 1.5rem 0;
}

.celebration-icons {
    display: flex;
    justify-content: center;
    gap: 20px;
    font-size: 2.5rem;
    margin-bottom: 1rem;
}

.feedback-success-title {
    font-size: 1.5rem;
    font-weight: 700;
    margin-bottom: 0.5rem;
    color: var(--accent-primary);
}

.success-message-text {
    font-size: 0.95rem;
    color: var(--text-primary);
    line-height: 1.6;
    opacity: 0.9;
}

.feedback-success-close-btn {
    margin-top: 1.5rem;
    padding: 8px 24px;
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid var(--border-main);
    color: var(--text-primary);
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s ease;
}

.feedback-success-close-btn:hover {
    background: rgba(255, 255, 255, 0.2);
    transform: translateY(-2px);
}

/* Celebration Animations */
.icon-floating {
    animation: icon-float 3s ease-in-out infinite;
}

.icon-pulsing {
    animation: icon-pulse 2s ease-in-out infinite;
}

.icon-twinkling {
    animation: icon-twinkle 1.5s ease-in-out infinite;
    display: inline-block;
}

/* Theme Adaptations */
/* The heading is a blue-to-violet gradient clipped to the text. That is the
   house style on the dark card. On the two light cards it is the only blue on
   the screen and it is faint -- the gradient's stops measure 2.46:1 and 2.63:1
   on the cream one, against the 3:1 that large bold text needs. These themes
   take the solid accent they already define instead: 5.07:1 on light, 4.00:1 on
   eye-saver. -webkit-text-fill-color has to be reset too, or the transparent
   fill from the rule above keeps winning and the text stays invisible. */
:root[data-theme="light"] .feedback-title,
:root[data-theme="eye-saver"] .feedback-title {
    background: none;
    -webkit-background-clip: border-box;
    background-clip: border-box;
    -webkit-text-fill-color: currentColor;
    color: var(--accent-primary);
}

:root[data-theme="light"] .feedback-glass-card {
    background: rgba(255, 255, 255, 0.8);
    border-color: var(--accent-primary);
}

:root[data-theme="eye-saver"] .feedback-glass-card {
    background: rgba(254, 252, 232, 0.8);
    /* The IDE's eye-saver --text-secondary is Solarized #839496, which measures
       4.31:1 on this cream card — just under the 4.5:1 body-text minimum. Set on
       the card so only the modal's own text darkens; the site's muted grey is
       untouched elsewhere. The value is the academy palette's eye-saver
       secondary, so it is a colour the design already uses. */
    --text-secondary: #6b5d3f;
}

@media (max-width: 1024px) and (orientation: portrait) {
.feedback-trigger-inline {
        padding: 4px 8px !important;
    }

    .feedback-trigger-inline .feedback-text {
        font-size: 11px !important;
    }
}

/* ── Inline footer trigger ───────────────────────────────────────────────────
   A <button>, because it opens a dialog rather than navigating, styled to sit
   unremarkably among the footer's links: it inherits their colour and type, so
   it matches whatever stylesheet owns the surrounding footer. Feedback used to
   float bottom-left on Tutorial Lab alone — pinned left only to avoid colliding
   with the theme FAB on the right — and was absent from the academy and every
   lesson. In the footer it needs no fixed position, collides with nothing, and
   can appear on every page. */
.foot-feedback {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: inherit;
    cursor: pointer;
    text-decoration: none;
}

.foot-feedback:hover {
    text-decoration: underline;
}

/* feedback.js toggles #feedback-success, #feedback-error and the form container
   with a bare .hidden class. That utility exists in styles.css but not in the
   academy stylesheet, so on those pages the success panel rendered inside the
   form and pushed the card from 644px to 962px — taller than the viewport.
   Scoped to the modal rather than defined globally, so it cannot collide with
   whatever .hidden means elsewhere on a host page. */
.feedback-modal .hidden {
    display: none;
}

/* The card got light and eye-saver overrides; its fields never did. They stayed
   on the dark-only rgba(0, 0, 0, 0.2) fill while their text follows
   --text-primary, so on the light themes dark ink sat on a dark wash and
   measured 2.03:1 — far under the 4.5:1 that form text needs. Pre-existing on
   the IDE; it simply became visible on far more pages once feedback moved into
   every footer. */
:root[data-theme="light"] .feedback-field input,
:root[data-theme="light"] .feedback-field select,
:root[data-theme="light"] .feedback-field textarea,
:root[data-theme="eye-saver"] .feedback-field input,
:root[data-theme="eye-saver"] .feedback-field select,
:root[data-theme="eye-saver"] .feedback-field textarea {
    background: rgba(255, 255, 255, 0.9);
    border-color: var(--border-main);
}

:root[data-theme="light"] .feedback-field ::placeholder,
:root[data-theme="eye-saver"] .feedback-field ::placeholder {
    color: var(--text-secondary);
    opacity: 1;
}

/* ── Floating trigger ────────────────────────────────────────────────────────
   Same visual treatment as the IDE's inline trigger — accent fill, white label,
   speech-bubble icon — so feedback looks like one control across the product.
   The IDE keeps its inline version because its footer strip is always on screen;
   content pages need this because their footer sits 5-7 screens down, which is
   what made a footer-only trigger unreachable in practice.

   Sits BELOW the theme FAB on the same right edge, so the two read as a pair
   without feedback being exiled to the opposite corner. Anchored near the bottom
   rather than computed from the FAB's height: the FAB's own media queries already
   lift it clear on small screens, so anchoring here keeps the two apart at every
   breakpoint without a second copy of those offsets to drift. Horizontal
   alignment does come from the FAB's published --pm-fab-right. */
.feedback-trigger-floating {
    position: fixed;
    right: var(--pm-fab-right, 16px);
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    z-index: 60;

    display: inline-flex;
    align-items: center;
    gap: 0;
    padding: 8px 10px;
    border: none;
    border-radius: 8px;
    background: var(--accent-fill);
    color: #fff;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    box-shadow: 0 4px 0 rgba(0, 0, 0, 0.2), 0 8px 15px rgba(0, 0, 0, 0.1);
    transition: transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275), box-shadow 0.2s ease;
}

.feedback-trigger-floating:hover {
    transform: translateY(-1px);
    box-shadow: 0 5px 0 rgba(0, 0, 0, 0.2), 0 10px 18px rgba(0, 0, 0, 0.14);
}

.feedback-trigger-floating:active {
    transform: translateY(2px);
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.1);
}

.feedback-trigger-floating .feedback-icon {
    font-size: 16px;
    line-height: 1;
}

/* Icon at rest, word on hover — the same ghost-then-reveal behaviour the theme
   FAB uses, so the two controls read as one family rather than two unrelated
   widgets. The icon alone is ambiguous (chat? comments? support?), and feedback
   is a decision people make rarely, so the label has to be recoverable; it just
   does not need to occupy a reading page permanently. Width is animated via
   max-width because the label has no fixed size. */
.feedback-trigger-floating .feedback-text {
    max-width: 0;
    margin-left: 0;
    opacity: 0;
    overflow: hidden;
    white-space: nowrap;
    transition: max-width 0.22s ease, opacity 0.18s ease, margin-left 0.22s ease;
}

.feedback-trigger-floating:hover .feedback-text,
.feedback-trigger-floating:focus-visible .feedback-text {
    max-width: 8rem;
    margin-left: 8px;
    opacity: 1;
}

/* Narrow screens: keep the icon, drop the word — the FAB shrinks here too. */
@media (max-width: 520px) {
    .feedback-trigger-floating {
        bottom: calc(14px + env(safe-area-inset-bottom, 0px));
    }
}

/* Touch devices never hover, so the label would never appear — the tooltip and
   aria-label carry the meaning there. */
@media (hover: none) {
    .feedback-trigger-floating .feedback-text {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .feedback-trigger-floating {
        transition: none;
    }

    .feedback-trigger-floating:hover,
    .feedback-trigger-floating:active {
        transform: none;
    }

    .feedback-trigger-floating .feedback-text {
        transition: none;
    }
}

/* ── One hover language for every door into this form ──────────────────────
   Feedback and Contact are the same errand wearing two controls, so they
   should answer the pointer the same way. Measured before this existed: five
   different behaviours across eleven page types, including two Feedback
   buttons that disagreed with each other about how far to lift and over what
   curve. Everything below shares 0.15s, the same easing and a 1px lift; the
   links add the accent the header nav already uses.

   Defined last in the file on purpose. Every rule it supersedes lives above it
   at the same specificity, so source order settles it and nothing here needs
   !important. Change the hover feel in one place, not five. */
.feedback-trigger-inline,
.feedback-trigger-floating {
    transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}
.feedback-trigger-inline:hover,
.feedback-trigger-floating:hover {
    transform: translateY(-1px);
    box-shadow: 0 5px 0 rgba(0, 0, 0, 0.2), 0 10px 18px rgba(0, 0, 0, 0.14);
    filter: brightness(1.06);
}
.feedback-trigger-inline:active,
.feedback-trigger-floating:active {
    transform: translateY(2px);
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.1);
    filter: none;
}

/* The text doors: footer Contact, the status bar's contact line, and the one
   inside the policy prose. A link cannot grow a shadow, so it takes the colour
   and the same 1px -- which is also what .info-link has always done in the
   IDE's own status bar. */
.foot .foot-contact[data-feedback-open],
.contact-link-btn[data-feedback-open],
.legal-contact-link[data-feedback-open] {
    transition: color 0.15s ease, opacity 0.15s ease, transform 0.15s ease;
    display: inline-block;
}
.foot .foot-contact[data-feedback-open]:hover,
.contact-link-btn[data-feedback-open]:hover,
.legal-contact-link[data-feedback-open]:hover {
    color: var(--accent-primary, var(--chrome-accent, #38bdf8));
    opacity: 1;
    transform: translateY(-1px);
}
.foot .foot-contact[data-feedback-open]:active,
.contact-link-btn[data-feedback-open]:active,
.legal-contact-link[data-feedback-open]:active {
    transform: translateY(0);
}
