/* ==========================================
   CosmicByMe Birthday Card Generator CSS
   Theme: Navy/Indigo Space with Neon/Pastel Accents
   ========================================== */

/* Variables */
:root {
    --bg-dark: #070913;
    --bg-card: rgba(15, 18, 36, 0.7);
    --border-neon: rgba(99, 102, 241, 0.3);
    --color-text: #e2e8f0;
    --color-muted: #94a3b8;
    
    /* Neon & Pastel Palette */
    --neon-blue: #00f0ff;
    --neon-purple: #bd00ff;
    --pastel-indigo: #818cf8;
    --pastel-pink: #f472b6;
    --neon-green: #10b981;
    --glass-glow: 0 8px 32px 0 rgba(99, 102, 241, 0.1);

    /* Dynamic Accent Color - defaults to Neon Indigo */
    --neon-accent: #6366f1;
    --neon-accent-glow: rgba(99, 102, 241, 0.3);

    /* Vertical space reserved *above and below* the card, beyond what the
       dock/header strictly require — without this the card's max-height
       formula fills every last pixel of remaining space and ends up flush
       against the dock with zero breathing room. On wide screens the header
       sits *beside* the card (row layout) so it costs the dock area almost
       nothing on its own; below 899px they stack (see the media query
       further down), and the header's real height (~160px+ with the
       wrapped subtitle) needs to be reserved on top of that margin. */
    --header-allowance: 160px;
}

/* Reset & Base Styles */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    background-color: var(--bg-dark);
    /* Faint nebula color glow, showing through the animated star canvas above it */
    background-image:
        radial-gradient(circle at 15% 20%, rgba(99, 102, 241, 0.28) 0%, transparent 45%),
        radial-gradient(circle at 85% 75%, rgba(189, 0, 255, 0.22) 0%, transparent 45%);
    color: var(--color-text);
    font-family: 'Noto Sans KR', sans-serif;
    line-height: 1.6;
    position: relative;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    /* Room for the fixed control dock at the bottom so it never covers content.
       The dock wraps to a different number of rows depending on viewport
       width (1 row on desktop, up to ~5 stacked on narrow phones), so a
       single static value here can't fit every case — too small and the
       dock covers the card's bottom, too large and it leaves a dead gap
       that pushes the card visually toward the top. --dock-height is kept
       in sync with the dock's real rendered height by syncDockHeight() in
       app.js (on load and on resize). */
    padding-bottom: calc(var(--dock-height, 130px) + 20px);
}

/* Full-screen canvas flying through a star field — see initWarpBackground() in app.js */
#warp-bg {
    position: fixed;
    inset: 0;
    z-index: -1;
    display: block;
    pointer-events: none;
}

/* Container — header sits beside the card as a left column on wide screens,
   stacks above it on narrow ones (see the max-width:899px query below). */
.container {
    max-width: 1300px;
    width: 100%;
    margin: 0 auto;
    padding: 0 15px;
    flex: 1;
    min-height: 0; /* without this, a flex item won't shrink below its content's
                       natural height, so .container grows to fit the tall card
                       instead of being bounded — breaking align-items:center */
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 40px;
}

/* Header */
header {
    text-align: left;
    flex: 0 0 300px;
    padding: 0;
}

header h1 {
    font-family: 'Orbitron', sans-serif;
    font-weight: 900;
    font-size: 2.2rem;
    letter-spacing: 2px;
    white-space: nowrap;
    background: linear-gradient(135deg, #fff 0%, var(--neon-accent) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    text-shadow: 0 0 30px var(--neon-accent-glow);
    margin-bottom: 10px;
    transition: background 0.5s ease, text-shadow 0.5s ease;
}

header .subtitle {
    font-size: 0.95rem;
    color: var(--color-muted);
    font-weight: 300;
}

/* Main — the card preview, centered in the remaining space beside the header */
main {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px 0;
    min-height: 0;
    min-width: 0;
}

/* Below this, a side-by-side header+card gets cramped — stack them instead */
@media (max-width: 899px) {
    :root {
        /* Header now sits above the card (stacked), not beside it — reserve
           its real height (~160px, more with a longer wrapped subtitle) so
           the card's own max-height formula doesn't oversize and overlap it. */
        --header-allowance: 220px;
    }

    .container {
        flex-direction: column;
        gap: 10px;
    }

    header {
        flex: none;
        text-align: center;
        padding-top: 20px;
    }

    header .subtitle {
        max-width: none;
    }
}

/* Preview Container — no glass panel/border anymore, the card just floats
   directly over the warp starfield background. */
.preview-container {
    width: 100%;
    max-width: 620px;
    padding: 0;
}

label {
    display: block;
    font-weight: 700;
    font-size: 0.8rem;
    margin-bottom: 6px;
    color: var(--pastel-indigo);
    letter-spacing: 0.5px;
}

input[type="date"],
input[type="text"] {
    width: 100%;
    padding: 10px 14px;
    background-color: rgba(5, 7, 18, 0.85);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    color: #fff;
    font-size: 0.9rem;
    transition: all 0.3s ease;
    font-family: inherit;
}

#custom-signature {
    width: 170px;
}

input:focus {
    outline: none;
    border-color: var(--neon-accent);
    box-shadow: 0 0 12px var(--neon-accent-glow);
}

.label-hint {
    font-weight: 400;
    font-size: 0.8rem;
    color: var(--color-muted);
    letter-spacing: normal;
}

/* Birth date/time dropdown row. Date (Y/M/D) and time (H:M) are each their
   own nested flex group so they wrap onto separate lines as a whole unit on
   narrow screens, instead of a lone select (e.g. minute) breaking off by itself. */
.datetime-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 14px;
}

.datetime-group {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 6px;
}

.datetime-row select {
    padding: 10px 6px;
    background-color: rgba(5, 7, 18, 0.85);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    color: #fff;
    font-size: 0.85rem;
    font-family: inherit;
    transition: all 0.3s ease;
    cursor: pointer;
}

.datetime-row select:focus {
    outline: none;
    border-color: var(--neon-accent);
    box-shadow: 0 0 12px var(--neon-accent-glow);
}

.datetime-row select:invalid,
.datetime-row select option[value=""] {
    color: var(--color-muted);
}

#birth-year { width: 68px; }
#birth-month,
#birth-day { width: 50px; }
#birth-hour,
#birth-minute { width: 50px; }

.datetime-at,
.datetime-colon {
    color: var(--color-muted);
    font-size: 0.85rem;
    flex-shrink: 0;
}

/* Geolocation row */
.location-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

/* Button Styles */
button {
    font-family: inherit;
    font-weight: 700;
    cursor: pointer;
    transition: all 0.3s ease;
    border-radius: 10px;
    border: none;
    outline: none;
}

.btn-secondary {
    padding: 12px 18px;
    font-size: 0.9rem;
    color: #fff;
    background-color: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.15);
}

.btn-secondary:hover {
    background-color: rgba(255, 255, 255, 0.1);
    border-color: var(--neon-accent);
    color: var(--neon-accent);
}

/* Pill-shaped action buttons, used in the bottom control dock */
.btn-round {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 9px 13px;
    border-radius: 999px;
    font-size: 0.82rem;
    color: #fff;
    background-color: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.15);
    white-space: nowrap;
}

.btn-round:hover:not(:disabled) {
    background-color: rgba(255, 255, 255, 0.12);
    border-color: var(--neon-accent);
    transform: translateY(-2px);
}

.btn-round svg {
    flex-shrink: 0;
}

/* GPS button once a location (real or fallback) has been set */
.btn-round.is-active {
    background-color: rgba(16, 185, 129, 0.18);
    border-color: var(--neon-green);
    color: var(--neon-green);
}

.btn-round.is-active:hover:not(:disabled) {
    background-color: rgba(16, 185, 129, 0.28);
}

.btn-round-primary {
    padding: 11px 24px;
    font-size: 0.9rem;
    color: #fff;
    background: linear-gradient(90deg, var(--neon-accent), var(--neon-purple));
    border: none;
    box-shadow: 0 4px 20px var(--neon-accent-glow);
}

.btn-round-primary:hover:not(:disabled) {
    box-shadow: 0 6px 25px var(--neon-accent);
}

button:disabled {
    opacity: 0.4;
    cursor: not-allowed;
    transform: none !important;
    box-shadow: none !important;
}

/* Control Dock — every input & action, pinned to the bottom of the screen */
.control-dock {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    background: rgba(7, 9, 19, 0.95);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-top: 1px solid var(--border-neon);
    box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.5);
    padding: 14px 20px;
}

/* .dock-inner is the one true flex row; <form> and .dock-actions are
   display:contents so their children (fields, buttons) join it directly
   instead of nesting as sub-rows — a single horizontal control bar. */
.dock-inner {
    max-width: 1700px;
    margin: 0 auto;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    flex-wrap: wrap;
    gap: 8px 12px;
}

.control-dock form,
.dock-actions {
    display: contents;
}

.dock-field {
    display: flex;
    flex-direction: column;
}

/* Preview Section Styling — no frame; the card floats directly on the
   starfield. No overflow:hidden — the idle-heartbeat glow (box-shadow, up
   to ~90px blur at the flash peak) needs room to fall off naturally; with
   it clipped at a 10px padding edge, the glow was getting hard-cut into a
   flat line at the wrapper's top/bottom instead of fading out. */
.canvas-wrapper {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 10px;
    margin-bottom: 10px;
}

/* Render 1080x1920 canvas responsibly inside container. Capped against the
   *actual* remaining space (viewport minus the dock's real height, which
   changes as the dock wraps to more rows on narrow screens — kept in sync
   via --dock-height, see syncDockHeight() in app.js) rather than a flat vh
   fraction, which on mobile let the card demand more height than was left
   after the dock and overlap it. The extra 100px covers the header, which
   sits above the card (not beside it) once they stack on narrow screens. */
#birthday-canvas {
    max-width: 100%;
    height: auto;
    aspect-ratio: 9 / 16;
    max-height: min(680px, calc(100vh - var(--dock-height, 130px) - var(--header-allowance)));
    border-radius: 10px;
    box-shadow: 0 15px 40px rgba(0,0,0,0.9);
    background: #000;
    display: block;
    cursor: zoom-in;
    transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.25, 1), box-shadow 0.3s ease, opacity 0.15s ease;
}

#birthday-canvas:hover {
    transform: scale(1.02);
    box-shadow: 0 20px 50px var(--neon-accent-glow), 0 0 30px rgba(99, 102, 241, 0.15);
}

/* Heartbeat-like pulse on the placeholder card, inviting generation — a
   real heartbeat isn't a smooth sine wave, it's a sharp "thump" then a
   longer rest (팍.....팍.....): fast attack (0%→8%), then a slower fade
   back down (8%→40%, ~4x longer than the attack) to a resting glow that
   never fully goes dark. The flash itself is white-hot (not just the
   accent-color glow) for real contrast. Removed the moment the user clicks
   Generate (see app.js) and re-added by initCanvasPlaceholder() on
   load/reset. */
#birthday-canvas.idle-pulse {
    animation: idle-heartbeat 1.8s ease-out infinite;
}

@keyframes idle-heartbeat {
    0%, 100% {
        opacity: 0.8;
        box-shadow: 0 15px 40px rgba(0,0,0,0.9), 0 0 18px rgba(99, 102, 241, 0.45);
        filter: brightness(1.05);
    }
    8% {
        opacity: 1;
        box-shadow: 0 0 90px rgba(255,255,255,0.95), 0 0 50px var(--neon-accent-glow);
        filter: brightness(1.35);
    }
    40% {
        opacity: 0.8;
        box-shadow: 0 15px 40px rgba(0,0,0,0.9), 0 0 18px rgba(99, 102, 241, 0.45);
        filter: brightness(1.05);
    }
}

/* Preview Status — a single evolving status line above the card preview,
   replacing the old multi-line system console. Empty/absent when idle. */
.preview-status {
    display: none;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-bottom: 14px;
    padding: 10px 16px;
    border-radius: 10px;
    background-color: rgba(0, 0, 0, 0.7);
    border: 1px solid rgba(255, 255, 255, 0.08);
    font-family: 'Consolas', 'Courier New', monospace;
    font-size: 0.85rem;
    text-align: center;
}

.preview-status.is-visible {
    display: flex;
}

.preview-status.status-system {
    color: var(--pastel-indigo);
}

.preview-status.status-system::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--pastel-indigo);
    box-shadow: 0 0 6px var(--pastel-indigo);
    animation: preview-status-pulse 1s ease-in-out infinite;
    flex-shrink: 0;
}

.preview-status.status-success {
    color: var(--neon-green);
    text-shadow: 0 0 5px rgba(16, 185, 129, 0.2);
}

.preview-status.status-error {
    color: var(--pastel-pink);
    text-shadow: 0 0 5px rgba(244, 114, 182, 0.2);
}

@keyframes preview-status-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.4; transform: scale(0.7); }
}

/* Footer */
/* Now the control dock's own last row (see index.html) -- centered under
   the Generate/Reset/Download buttons, in normal document flow, rather
   than a separately-fixed corner element. (That approach used to overlap
   the dock's own buttons once they wrapped to extra rows on mobile.) */
footer {
    width: 100%;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border-neon);
    color: var(--color-muted);
    font-size: 0.72rem;
    opacity: 0.7;
    text-align: center;
}

.footer-links {
    display: flex;
    gap: 12px;
    justify-content: center;
    flex-wrap: wrap;
    margin-bottom: 4px;
}

.footer-links a {
    color: var(--color-muted);
    text-decoration: none;
}

.footer-links a:hover {
    color: var(--pastel-indigo);
    text-decoration: underline;
}

/* "Hero" reveal: the card leaves its normal spot the instant generation
   starts, spins as it grows to screen center, then sits there tiltable
   (poke-holo style) once real content is ready. On click it flies back to
   its spot before the zoom modal takes over. Sits below .card-modal
   (z-index 1000) since the two are never shown together. */
.card-hero {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 900;
    align-items: center;
    justify-content: center;
    pointer-events: none; /* only card-hero-img itself captures clicks, so the
                              rest of the page (e.g. the Download button)
                              stays reachable while the hero is shown */
}

.card-hero.show {
    display: flex;
}

/* Carries the one-shot move/grow(/shrink-back) transition — kept separate
   from card-hero-img's own transform so that transition can coexist with
   the img's infinite spin animation and mouse-tilt transform. */
.card-hero-pos {
    width: min(78vw, 420px);
    aspect-ratio: 9 / 16;
}

.card-hero-img {
    width: 100%;
    height: 100%;
    aspect-ratio: 9 / 16;
    border-radius: 14px;
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.85), 0 0 60px var(--neon-accent-glow);
    border: 1px solid var(--border-neon);
    display: block;
    cursor: zoom-in;
    user-select: none;
    -webkit-user-drag: none;
    will-change: transform;
    pointer-events: auto;
}

/* Slightly smaller resting size for the empty/placeholder card, before the
   first card has ever been generated (see initCanvasPlaceholder()). */
#birthday-canvas.canvas-compact {
    max-height: min(560px, calc(100vh - var(--dock-height, 130px) - var(--header-allowance)));
}

/* Floating Zoom Modal / Lightbox Styles */
.card-modal {
    display: none; /* Hidden by default */
    position: fixed;
    z-index: 1000; /* Sit on top */
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto; /* Enable scroll if needed */
    background-color: rgba(5, 7, 18, 0.85); /* Blackout background */
    backdrop-filter: blur(15px); /* Smooth blurry backdrop */
    -webkit-backdrop-filter: blur(15px);
    justify-content: center;
    align-items: center;
    opacity: 0;
    transition: opacity 0.3s ease;
}

.card-modal.show {
    display: flex;
    opacity: 1;
}

.modal-content-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    max-width: 90%;
    max-height: 90%;
    position: relative;
}

.modal-card-img {
    max-height: 80vh; /* Scaled to 80% viewport height */
    width: auto;
    aspect-ratio: 9 / 16;
    border-radius: 14px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.9), 0 0 40px var(--neon-accent-glow);
    border: 1px solid var(--border-neon);
    display: block;
    user-select: none;
    -webkit-user-drag: none;
    transition: transform 0.2s ease;
    cursor: zoom-out;
}

.modal-close {
    position: absolute;
    top: 25px;
    right: 40px;
    color: #f3f4f6;
    font-size: 50px;
    font-weight: 300;
    cursor: pointer;
    transition: color 0.2s ease, transform 0.2s ease;
    user-select: none;
    z-index: 1010;
}

.modal-close:hover {
    color: var(--pastel-pink);
    transform: scale(1.1);
}

.modal-tip {
    margin-top: 15px;
    font-size: 0.9rem;
    color: var(--color-muted);
    letter-spacing: 0.5px;
    text-align: center;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
    font-family: inherit;
    animation: pulse-tip 2.5s infinite;
}

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

/* ==========================================
   Content Pages (About / Privacy / Terms / Contact / Blog)
   Shared chrome for the static informational pages — a simple top nav,
   a readable centered article column, and a normal (non-fixed) footer.
   Kept visually consistent with the app (same dark bg, neon accent,
   Orbitron headings) but laid out for reading, not for the card tool.
   ========================================== */
body.content-page {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    padding: 0;
    padding-bottom: 0;
}

.site-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    padding: 20px 32px;
    position: relative;
    z-index: 5;
}

.site-nav .brand {
    font-family: 'Orbitron', sans-serif;
    font-weight: 900;
    font-size: 1.3rem;
    color: var(--color-text);
    text-decoration: none;
    background: linear-gradient(135deg, #fff 0%, var(--neon-accent) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
}

.site-nav .nav-links {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
}

.site-nav .nav-links a {
    color: var(--color-muted);
    text-decoration: none;
    font-size: 0.9rem;
}

.site-nav .nav-links a:hover,
.site-nav .nav-links a.active {
    color: var(--pastel-indigo);
}

.content-page main {
    display: block;
    flex: 1;
    max-width: 760px;
    width: 100%;
    margin: 0 auto;
    padding: 20px 24px 80px;
    position: relative;
    z-index: 5;
}

.content-page h1 {
    font-family: 'Orbitron', sans-serif;
    font-weight: 900;
    font-size: 2rem;
    margin-bottom: 8px;
    color: var(--color-text);
}

.content-page .page-subtitle {
    color: var(--color-muted);
    margin-bottom: 32px;
    font-size: 0.95rem;
}

.content-page h2 {
    font-family: 'Orbitron', sans-serif;
    font-size: 1.2rem;
    color: var(--pastel-indigo);
    margin: 36px 0 12px;
}

.content-page h3 {
    font-size: 1.05rem;
    color: var(--color-text);
    margin: 24px 0 10px;
}

.content-page p {
    color: var(--color-text);
    line-height: 1.75;
    margin-bottom: 16px;
    font-size: 0.98rem;
}

.content-page ul,
.content-page ol {
    color: var(--color-text);
    line-height: 1.75;
    margin: 0 0 16px 22px;
    font-size: 0.98rem;
}

.content-page li {
    margin-bottom: 6px;
}

.content-page a {
    color: var(--pastel-indigo);
}

.content-page strong {
    color: #fff;
}

.content-page .updated-date {
    color: var(--color-muted);
    font-size: 0.85rem;
    margin-bottom: 32px;
}

.content-page .card-box {
    background: var(--bg-card);
    border: 1px solid var(--border-neon);
    border-radius: 12px;
    padding: 20px 24px;
    margin: 24px 0;
}

.site-footer {
    position: relative;
    z-index: 5;
    text-align: center;
    padding: 24px;
    color: var(--color-muted);
    font-size: 0.8rem;
    border-top: 1px solid rgba(148, 163, 184, 0.12);
}

.site-footer a {
    color: var(--color-muted);
    text-decoration: none;
    margin: 0 8px;
}

.site-footer a:hover {
    color: var(--pastel-indigo);
}

/* Blog listing */
.blog-grid {
    display: grid;
    gap: 20px;
    margin-top: 24px;
}

.blog-card {
    display: block;
    background: var(--bg-card);
    border: 1px solid var(--border-neon);
    border-radius: 12px;
    padding: 20px 24px;
    text-decoration: none;
    transition: border-color 0.2s ease, transform 0.2s ease;
}

.blog-card:hover {
    border-color: var(--neon-accent);
    transform: translateY(-2px);
}

.blog-card .blog-card-date {
    color: var(--color-muted);
    font-size: 0.8rem;
    margin-bottom: 6px;
}

.blog-card .blog-card-title {
    font-family: 'Orbitron', sans-serif;
    font-size: 1.05rem;
    color: var(--color-text);
    margin-bottom: 8px;
}

.blog-card .blog-card-excerpt {
    color: var(--color-muted);
    font-size: 0.9rem;
    line-height: 1.6;
}

.blog-empty {
    color: var(--color-muted);
    font-size: 0.95rem;
    padding: 40px 0;
    text-align: center;
}

/* Contact form */
.contact-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: 480px;
}

.contact-form label {
    color: var(--color-muted);
    font-size: 0.85rem;
    margin-bottom: 6px;
    display: block;
}

.contact-form input,
.contact-form textarea {
    width: 100%;
    background: rgba(15, 18, 36, 0.7);
    border: 1px solid var(--border-neon);
    border-radius: 8px;
    padding: 10px 14px;
    color: var(--color-text);
    font-family: inherit;
    font-size: 0.95rem;
}

.contact-form textarea {
    resize: vertical;
    min-height: 120px;
}

.contact-form input:focus,
.contact-form textarea:focus {
    outline: none;
    border-color: var(--neon-accent);
}
