/* hook test */
/* Grid Mode Styles
 * Browse/discovery view showing multiple flashcards in a grid
 * Desktop-only: Multi-column grid with click-to-focus
 * Updated: 2026-02-25 (hook test)
 *
 * Premium Polish Features:
 * - Staggered card entrance animations
 * - Enhanced hover states with depth
 * - Smooth 3D flip with perspective
 * - Micro-interactions on buttons
 * - Animated filter chips
 */

/* =============================================================================
   CSS CUSTOM PROPERTIES (Design Tokens)
   ============================================================================= */

:root {
    /* Card colors */
    --grid-card-bg: rgba(250, 250, 247, 0.94);
    --grid-card-border: rgba(44, 44, 44, 0.04);
    --grid-card-shadow: 0 1px 3px rgba(44, 44, 44, 0.04), 0 4px 12px rgba(44, 44, 44, 0.03);
    --grid-card-shadow-hover: 0 1px 3px rgba(44, 44, 44, 0.04), 0 4px 16px rgba(61, 90, 128, 0.06);

    /* Text colors */
    --grid-japanese-color: #332F2B;  /* Warm sumi ink */
    --grid-romanization-color: #4A4642;

    /* Button colors */
    --grid-audio-btn: rgba(61, 90, 128, 0.85);
    --grid-audio-btn-hover: rgba(61, 90, 128, 1);
    --grid-focus-btn: rgba(61, 90, 128, 0.85);
    --grid-focus-btn-hover: rgba(61, 90, 128, 1);
    --grid-known-btn: rgba(163, 177, 138, 0.85);
    --grid-learning-btn: rgba(194, 130, 114, 0.85);

    /* Animation timing */
    --grid-transition-fast: 0.15s;
    --grid-transition-medium: 0.25s;
    --grid-transition-slow: 0.4s;
    --grid-flip-duration: 0.45s;

    /* Easing functions */
    --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-out-back: cubic-bezier(0.34, 1.56, 0.64, 1);
    --ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

/* =============================================================================
   MODE VISIBILITY
   ============================================================================= */

/* Hide flashcard container and related elements in grid mode */
/* NOTE: Must match specificity of standard-mode.css selector:
   body:not(.focus-mode):not(.video-mode) .flashcard-container { display: flex !important; }
   Adding :not() pseudo-classes to match specificity (0,0,4,1) */
body.grid-mode:not(.focus-mode):not(.video-mode) .flashcard-container,
body.grid-mode:not(.focus-mode):not(.video-mode) .premium-progress-wrapper {
    display: none !important;
}

/* Also hide the single card view elements */
body.grid-mode .flashcard {
    display: none !important;
}

/* Hide focus-only elements in grid mode */
body.grid-mode .focus-exit-button,
body.grid-mode .japanese-flag,
body.grid-mode .lower-third,
body.grid-mode .channel-logo-badge,
body.grid-mode .category-badge,
body.grid-mode .lesson-badge,
body.grid-mode .screen-category-indicator,
body.grid-mode .mobile-exit-group,
body.grid-mode #card-number {
    display: none !important;
}

/* =============================================================================
   GRID CONTAINER - FLEX LAYOUT INTEGRATION
   ============================================================================= */

/* Grid container participates in the flex layout hierarchy */
.grid-container {
    display: none;  /* Hidden by default, shown in grid mode */
    flex: 1;        /* Take available space like flashcard-container */
    flex-direction: column;
    width: 100%;
    max-width: 1800px;    /* Wider on desktop for more cards */
    margin: 0 auto;
    margin-top: var(--top-bar-height, 90px);  /* Account for fixed top bar */
    padding: 12px 40px 20px;   /* Reduced top padding for balanced spacing */
    overflow-y: auto;     /* Scroll within the flex item */
    box-sizing: border-box;
    /* Establish stacking context below nav bar (z-index: 98) */
    position: relative;
    z-index: 1;
    isolation: isolate;  /* Contain 3D transformed cards within this context */
    /* Smooth push when sidebars open */
    transition: margin-left 250ms cubic-bezier(0.16, 1, 0.3, 1),
                margin-right 250ms cubic-bezier(0.16, 1, 0.3, 1),
                max-width 250ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* Push grid right when browse sidebar is open (sidebar flush at left:0) */
body.browse-sidebar-open .grid-container {
    margin-left: var(--sidebar-w, 260px);
    max-width: min(1800px, calc(100% - var(--sidebar-w, 260px)));
}


/* When grid mode is active, show grid container with flex display.
   margin-top is driven by --nav-bar-total-height (set by ResizeObserver in JS,
   consumed in ink-wash-tabs.css) — no hardcoded values here. */
body.grid-mode .grid-container {
    display: flex;
}

/* Keep grid layout tree warm during focus mode to avoid 200ms+ reflow
   when returning. visibility:hidden preserves layout; display:none destroys it. */
.grid-container.grid-warm {
    display: flex !important;
    visibility: hidden;
    position: absolute;
    pointer-events: none;
    height: 0;
    overflow: hidden;
}
body.grid-mode .grid-container.grid-warm {
    visibility: visible;
    position: relative;
    pointer-events: auto;
    height: auto;
    overflow-y: auto;
}

/* Header icon buttons — warm neutral, deferential (落款 seal-stamp quiet) */
body.grid-mode .icon-btn {
    width: 40px;
    height: 40px;
    background: rgba(44, 44, 44, 0.03);
    border: none;
    color: #78716c;
    font-size: 16px;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

body.grid-mode .icon-btn:hover {
    background: rgba(44, 44, 44, 0.06);
    color: #57534e;
    transform: none;
}

body.grid-mode .icon-btn:active {
    background: rgba(44, 44, 44, 0.08);
    transform: scale(0.96);
}

/* Segmented control (Kana/Kanji toggle) - Premium style */
.nav-segmented-control {
    display: flex;
    border-radius: 22px;
    border: 1px solid rgba(255, 255, 255, 0.4);
    background: rgba(255, 255, 255, 0.5);
    backdrop-filter: blur(7px);
    -webkit-backdrop-filter: blur(7px);
    padding: 4px;
    gap: 2px;
    box-shadow: inset 0 1px 2px rgba(44, 44, 44, 0.02);
}

.segment-btn {
    display: flex;
    align-items: center;
    gap: 5px;
    height: 32px;
    padding: 0 14px;
    border-radius: 18px;
    border: none;
    background: transparent;
    color: #6b7280;
    font-family: 'Inter', sans-serif;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition:
        all var(--grid-transition-fast) ease,
        transform var(--grid-transition-fast) var(--ease-out-back);
}

.segment-btn:hover:not(.active) {
    background: rgba(255, 255, 255, 0.6);
    color: #374151;
}

.segment-btn.active {
    background: #FAFAF7;
    color: #374151;
    box-shadow:
        0 2px 8px rgba(44, 44, 44, 0.06),
        0 1px 2px rgba(44, 44, 44, 0.04);
    transform: scale(1.02);
}

.segment-btn .segment-icon {
    font-size: 13px;
    font-weight: 700;
}

/* =============================================================================
   CARD GRID - DESKTOP
   ============================================================================= */

.grid-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(400px, calc(50% - 14px)), 1fr));
    justify-content: center;  /* Center when cards don't stretch to fill */
    gap: 28px;
    padding: 20px;
    flex: 1;            /* Take remaining space in grid-container */
    align-content: start; /* Align cards to top, not stretch */
    /* Perspective moved to individual .grid-card for better per-card depth */
}

/* =============================================================================
   STAGGERED ENTRANCE ANIMATION
   ============================================================================= */

@keyframes cardEntrance {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Card exit animation - two-phase: fade+scale then height collapse
   Phase 1 (0-50%): Visual exit - fade out + scale down
   Phase 2 (50-100%): Height collapse - smooth gap closure
   NOTE: .exiting also sets min-height: 0 !important to override mobile min-height */
@keyframes cardExit {
    0% {
        opacity: 1;
        transform: translateY(0) scale(1);
        height: var(--card-exit-height, 200px);
        margin-bottom: 0;
    }
    40% {
        opacity: 0;
        transform: translateY(-20px) scale(0.85);
        height: var(--card-exit-height, 200px);
        margin-bottom: 0;
    }
    100% {
        opacity: 0;
        transform: translateY(-20px) scale(0.85);
        height: 0;
        margin-bottom: -16px;  /* Eat the grid gap */
        padding: 0;
        border-width: 0;
    }
}

.grid-card.exiting {
    animation: cardExit 0.6s var(--ease-out-expo) forwards !important;
    pointer-events: none;
    overflow: hidden;
    min-height: 0 !important;  /* Override mobile min-height: 160px so height can collapse */
}

.grid-card {
    animation: cardEntrance 0.6s var(--ease-out-expo) backwards;
}

/* Stagger animation — 40ms per card for gentle wave (流れ) */
.grid-card:nth-child(1) { animation-delay: 0.04s; }
.grid-card:nth-child(2) { animation-delay: 0.08s; }
.grid-card:nth-child(3) { animation-delay: 0.12s; }
.grid-card:nth-child(4) { animation-delay: 0.16s; }
.grid-card:nth-child(5) { animation-delay: 0.20s; }
.grid-card:nth-child(6) { animation-delay: 0.24s; }
.grid-card:nth-child(7) { animation-delay: 0.28s; }
.grid-card:nth-child(8) { animation-delay: 0.32s; }
.grid-card:nth-child(9) { animation-delay: 0.36s; }
.grid-card:nth-child(10) { animation-delay: 0.40s; }
.grid-card:nth-child(11) { animation-delay: 0.44s; }
.grid-card:nth-child(12) { animation-delay: 0.48s; }
.grid-card:nth-child(13) { animation-delay: 0.52s; }
.grid-card:nth-child(14) { animation-delay: 0.56s; }
.grid-card:nth-child(15) { animation-delay: 0.60s; }
.grid-card:nth-child(16) { animation-delay: 0.64s; }
.grid-card:nth-child(17) { animation-delay: 0.68s; }
.grid-card:nth-child(18) { animation-delay: 0.72s; }
.grid-card:nth-child(19) { animation-delay: 0.76s; }
.grid-card:nth-child(20) { animation-delay: 0.80s; }
.grid-card:nth-child(n+21) { animation-delay: 0.84s; }

/* =============================================================================
   GRID CARD COMPONENT
   ============================================================================= */

/* =============================================================================
   GRID CARD COMPONENT - Premium Design
   ============================================================================= */

/* Paper Card - Material honesty with subtle top-edge highlight */
.grid-card {
    position: relative;
    background: #FEFDFB;  /* Pure warm white — cleaner figure/ground vs body */
    border-radius: 14px;
    overflow: hidden;
    cursor: pointer;
    aspect-ratio: 1 / 1;  /* Square — generous image space, uniform grid rhythm */
    border: 1px solid rgba(44, 44, 44, 0.05);
    border-top: 1px solid rgba(255, 255, 255, 0.7);  /* Top-edge highlight (paper catching light) */
    /* Removed backdrop-filter blur — no longer needed on opaque surface */
    /* Cards rest on surface, not float — flat shadows within 0.03-0.06 range */
    box-shadow:
        0 1px 3px rgba(44, 44, 44, 0.04),
        0 4px 12px rgba(44, 44, 44, 0.03);

    transition:
        transform 0.2s ease-out,
        box-shadow 0.4s cubic-bezier(0.22, 1, 0.36, 1),
        border-color 0.4s cubic-bezier(0.22, 1, 0.36, 1),
        margin-top 0.35s cubic-bezier(0.16, 1, 0.3, 1);

    /* Enable 3D transforms — perspective only on flip to avoid 800+ stacking contexts */
    transform-style: preserve-3d;

    /* Stable scroll with 800+ cards — give browser accurate height hints */
    content-visibility: auto;
    contain-intrinsic-size: auto 480px; /* 1:1 square at max grid column width */
}

/* Organic hover — gentle lift + subtle shadow deepening */
.grid-card:hover {
    transform: translateY(-1px);
    box-shadow:
        0 2px 6px rgba(44, 44, 44, 0.05),
        0 6px 16px rgba(44, 44, 44, 0.04);
    border-color: rgba(61, 90, 128, 0.10);
}

/* Active/pressed — subtle compression like pressing paper to table */
.grid-card:active {
    box-shadow:
        0 1px 2px rgba(44, 44, 44, 0.04),
        0 2px 6px rgba(44, 44, 44, 0.03);
    transition-duration: 0.1s;
}

/* Keep card stable when clicking peek strip or status buttons (prevent hover-lift bounce) */
.grid-card:has(.grid-card-rel-peek:active),
.grid-card:has(.grid-card-status-btn:active) {
    transform: none !important;
}

/* Card flip container - Enhanced 3D flip */
.grid-card-inner {
    position: relative;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    transition: transform var(--grid-flip-duration) ease-out;
}

/* Flipped state — add perspective only when needed to avoid 800+ stacking contexts */
.grid-card.flipped,
.grid-card.flipping {
    perspective: 1200px;
}
.grid-card.flipped .grid-card-inner {
    transform: rotateY(180deg);
}

/* No-transition helper for bulk operations */
.grid-cards.no-flip-transition .grid-card-inner {
    transition: none !important;
}

/* Bulk 3D flip — all cards show back face */
.grid-cards.cards-flipped .grid-card-inner {
    transform: rotateY(180deg);
}

/* XOR: individually flipped cards cancel out → show front */
.grid-cards.cards-flipped .grid-card.flipped .grid-card-inner {
    transform: rotateY(0deg);
}

.grid-cards.cards-flipped .grid-card-front {
    pointer-events: none;
}

.grid-cards.cards-flipped .grid-card-back {
    pointer-events: auto;
}

/* XOR: cancel pointer events for individually flipped cards */
.grid-cards.cards-flipped .grid-card.flipped .grid-card-front {
    pointer-events: auto;
}

.grid-cards.cards-flipped .grid-card.flipped .grid-card-back {
    pointer-events: none;
}

/* Scale pulse during flip for premium feel */
@keyframes flipPulse {
    0% { transform: rotateY(0deg) scale(1); }
    50% { transform: rotateY(90deg) scale(1.05); }
    100% { transform: rotateY(180deg) scale(1); }
}

.grid-card.flipping .grid-card-inner {
    animation: flipPulse var(--grid-flip-duration) var(--ease-out-expo) forwards;
}

/* Disable pointer events on front face when 3D-flipped (desktop) */
.grid-card.flipped .grid-card-front {
    pointer-events: none;
}

.grid-card.flipped .grid-card-back {
    pointer-events: auto;
}

/* Card faces */
.grid-card-front,
.grid-card-back {
    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    display: flex;
    flex-direction: column;
    border-radius: 14px;
    overflow: hidden;
}

/* Status indication handled on back-face children (.grid-card-back-content, .grid-card-rel)
   because card faces are position:absolute and cover the parent — inset shadows on .grid-card are hidden */

.grid-card-back {
    transform: rotateY(180deg);
    background: #FAFAF7;
}

/* Status dot — top-right corner, visible at rest, hides on hover as action buttons appear */
.grid-card-back::before {
    content: '';
    position: absolute;
    top: 18px;
    right: 18px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    opacity: 0;
    z-index: 6;
    pointer-events: none;
    transition: opacity 0.25s ease;
}

.grid-card-back.known::before {
    background: var(--color-moss);
    opacity: 0.7;
}

.grid-card-back.learning::before {
    background: var(--color-amber);
    opacity: 0.65;
}

/* Hide dot on hover — action buttons (⛶ ⋯ 🎧) take over the top-right zone */
.grid-card:hover .grid-card-back::before {
    opacity: 0;
}

/* Left-edge earned border for back face — inset shadow follows card border-radius */
.grid-card-back.known {
    box-shadow: inset 3px 0 0 0 rgba(107, 127, 92, 0.45);
}

.grid-card-back.learning {
    box-shadow: inset 3px 0 0 0 rgba(160, 120, 80, 0.4);
}

/* =============================================================================
   CARD BACK - SPLIT LAYOUT (Image + English)
   ============================================================================= */

/* Back image container - matches front style */
.grid-card-back-image {
    flex: 1;
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12px;  /* Compact — maximize image in flex layout */
    min-height: 0;
}

/* Back image - contained like front */
.grid-card-back-image img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: 12px;
}

.grid-card-back-image .grid-card-image-placeholder {
    width: 80px;
    height: 80px;
    background: rgba(61, 90, 128, 0.15);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
}

/* Color tint overlay - hidden */
.grid-card-back-tint {
    display: none;
}

/* =============================================================================
   CARD FRONT
   ============================================================================= */

.grid-card-image {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: rgba(61, 90, 128, 0.03);
    min-height: 0;
    position: relative;
    overflow: hidden;
}

/* Shimmer overlay removed (gradient purge) */
.grid-card-image::before {
    display: none;
}

.grid-card-image img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    border-radius: 12px;
    transition:
        transform var(--grid-transition-medium) var(--ease-out-expo),
        opacity 0.3s ease-out,
        filter 0.3s ease-out;
}

/* Shimmer animation for loading placeholders */
@keyframes shimmer {
    0% { background-position: -200% 0; }
    100% { background-position: 200% 0; }
}

/* Shimmer placeholder on image container while loading */
.grid-card-back-image.img-loading,
.grid-card-image.img-loading {
    background: linear-gradient(
        90deg,
        rgba(61, 90, 128, 0.04) 25%,
        rgba(61, 90, 128, 0.08) 50%,
        rgba(61, 90, 128, 0.04) 75%
    );
    background-size: 200% 100%;
    animation: shimmer 1.5s ease-in-out infinite;
}

/* Image loading state - hidden until loaded */
.grid-card-image img.loading,
.grid-card-back-image img.loading {
    opacity: 0;
}

/* Image loaded state - smooth fade in */
.grid-card-image img.loaded,
.grid-card-back-image img.loaded {
    opacity: 1;
    transition: opacity 0.25s ease;
}

/* No image zoom on hover — one gesture only */
.grid-card:hover .grid-card-image img {
    transform: none;
}

/* Placeholder when no image */
.grid-card-image-placeholder {
    width: 80px;
    height: 80px;
    background: rgba(61, 90, 128, 0.08);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
    color: var(--text-secondary, #a0a0a8);
    transition: transform var(--grid-transition-medium) ease;
}

.grid-card:hover .grid-card-image-placeholder {
    transform: scale(1.1) rotate(5deg);
}

/* Front: hide image — clean text-only face, image reveals on flip */
.grid-card-front .grid-card-image {
    display: none;
}

.grid-card-front {
    flex-direction: row;
    align-items: center;
    padding: 12px 16px;
    gap: 12px;
}

.grid-card-front .grid-card-content {
    flex: 1;
    border-top: none;
    padding: 0;
    position: relative;
    min-height: 48px;
}

/* Content area - min-height keeps short words centered, long words can grow */
.grid-card-content {
    min-height: 72px;
    flex-shrink: 0;
    padding: 12px 14px;
    text-align: center;
    border-top: 1px solid rgba(61, 90, 128, 0.08);
    background: rgba(255, 255, 255, 0.15);
    position: relative;
    transition: background 0.3s ease, border-color 0.3s ease;
    /* Center text vertically within content area */
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

/* Content area stays clean — status shown via bottom bar + buttons */

/* Dynamic Japanese text scaling based on character count */
/* Front is text-only so scale generously; back still has image */
.grid-card-japanese {
    font-family: 'Klee One', 'Noto Sans JP', sans-serif;
    font-size: clamp(2.2rem, calc(22rem / var(--ja-chars, 5)), 4.5rem);
    font-weight: 600;
    color: var(--grid-japanese-color);
    margin-bottom: 4px;
    line-height: 1.3;
    letter-spacing: 0.01em;  /* Tighter for kanji pairs */
    /* Ink absorption — sumi bleeding into washi paper */
    text-shadow: 0 0 0.5px rgba(44, 44, 44, 0.12);  /* Lowered from 0.15 */
    transition: color 0.4s ease, text-shadow 0.4s ease;
    /* Allow wrapping for longer words */
    word-break: keep-all;
    overflow-wrap: break-word;
}

/* Attention sharpening on hover — like focusing your eyes, warm focus */
.grid-card:hover .grid-card-japanese {
    color: #1C1A18;  /* Warm focus state - not neutral */
    text-shadow: 0 0 0.3px rgba(28, 26, 24, 0.15);  /* Deepen on hover */
}

/* Front-face audio button — hover reveal on desktop, matches back-face style */
.grid-card-front-audio {
    position: absolute;
    top: 14px;
    right: 16px;
    z-index: 5;
    width: 40px;
    height: 40px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: #78716c;
    font-size: 1.1rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    opacity: 0;
    transform: scale(0.92);
    transition: all 0.2s ease, opacity 0.25s ease, transform 0.25s ease;
    -webkit-tap-highlight-color: transparent;
    padding: 0;
}

.grid-card:hover .grid-card-front-audio {
    opacity: 0.7;
    transform: scale(1);
}

.grid-card-front-audio:hover {
    opacity: 1 !important;
    background: rgba(44, 44, 44, 0.04);
}

.grid-card-front-audio:active {
    transform: scale(0.92);
    transition-duration: 0.1s;
}

.grid-card-front-audio.playing {
    animation: audioPulse 1s ease-out;
}

/* Romanization - hidden by default, revealed on audio click */
.grid-card-front .grid-card-romanization {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    font-size: 1.4rem;
    font-style: normal;
    font-weight: 500;
    color: var(--grid-romanization-color);
    margin-top: 4px;
    padding-right: 4px;  /* Prevent italic overhang clipping */
    opacity: 0;
    max-height: 0;
    overflow: hidden;
    transform: translateY(-5px);
    transition:
        opacity var(--grid-transition-medium) ease,
        max-height var(--grid-transition-medium) ease,
        transform var(--grid-transition-medium) var(--ease-out-expo);
}

/* Show romanization when audio has been played - smooth reveal */
.grid-card.audio-played .grid-card-front .grid-card-romanization {
    opacity: 1;
    max-height: 2em;
    transform: translateY(0);
}

.grid-card-english {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    font-size: 1.35rem;  /* Down from 1.5rem — less decorative */
    font-weight: 400;  /* Down from 500 — secondary to image */
    color: #57534e;  /* Warm stone — not coral */
    letter-spacing: 0.01em;
    line-height: 1.4;
}


/* Audio playing pulse animation */
@keyframes audioPulse {
    0% { box-shadow: 0 2px 8px rgba(61, 90, 128, 0.3), 0 0 0 0 rgba(61, 90, 128, 0.4); }
    50% { box-shadow: 0 2px 8px rgba(61, 90, 128, 0.3), 0 0 0 8px rgba(61, 90, 128, 0); }
    100% { box-shadow: 0 2px 8px rgba(61, 90, 128, 0.3), 0 0 0 0 rgba(61, 90, 128, 0); }
}

.grid-card-audio.playing {
    animation: audioPulse 1s ease-out;
}

/* Focus button — top-right, left of story + audio buttons, appears on hover */
.grid-card-focus-btn {
    position: absolute;
    top: 14px;
    right: 108px;
    width: 40px;
    height: 40px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: #78716c;
    font-size: 1.15rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    z-index: 5;
    opacity: 0;
    transform: scale(0.92);
    transition: all 0.2s ease, opacity 0.25s ease, transform 0.25s ease;
    -webkit-tap-highlight-color: transparent;
    padding: 0;
}

.grid-card:hover .grid-card-focus-btn {
    opacity: 0.7;
    transform: scale(1);
}

.grid-card-focus-btn:hover {
    opacity: 1 !important;
    background: rgba(44, 44, 44, 0.04);
}

.grid-card-focus-btn:active {
    transform: scale(0.92);
    transition-duration: 0.1s;
}

/* Front-face focus button — left of audio button, hover reveal */
.grid-card-front-focus {
    right: 16px;
}

.grid-card-front:has(.grid-card-front-audio) .grid-card-front-focus {
    right: 60px;
}

/* Card number - position/total like focus mode */
.grid-card-number {
    position: absolute;
    top: 12px;
    left: 12px;
    padding: 4px 10px;
    background: rgba(61, 90, 128, 0.87);
    backdrop-filter: blur(5px);
    -webkit-backdrop-filter: blur(5px);
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    font-family: 'Inter', sans-serif;
    font-size: 0.7rem;
    font-weight: 700;
    color: white;
    z-index: 5;
    letter-spacing: 0.02em;
}

/* Status indicator - HIDDEN (using left border + content tint instead) */
.grid-card-status {
    display: none;
}

/* Status indicator animations */
@keyframes statusPop {
    0% { transform: scale(1); }
    50% { transform: scale(1.3); }
    100% { transform: scale(1); }
}

.grid-card-status.known {
    background: rgba(163, 177, 138, 0.85);
    border-color: rgba(163, 177, 138, 0.6);
    box-shadow:
        0 0 0 3px rgba(163, 177, 138, 0.09),
        0 2px 8px rgba(163, 177, 138, 0.15);
    animation: statusPop 0.3s var(--ease-out-back);
}

.grid-card-status.learning {
    background: rgba(194, 130, 114, 0.85);
    border-color: rgba(194, 130, 114, 0.6);
    box-shadow:
        0 0 0 3px rgba(194, 130, 114, 0.09),
        0 2px 8px rgba(194, 130, 114, 0.15);
    animation: statusPop 0.3s var(--ease-out-back);
}

/* =============================================================================
   TEXT FLIP — CSS overlay swap (Phase 1)
   Only targets front-face elements. Back face is NEVER affected.
   ============================================================================= */

/* English text overlay — hidden by default, positioned over Japanese */
.grid-card-english-swap {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    font-size: 1.3rem;
    font-weight: 500;
    color: #2C2C2C;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
    padding: 0 8px;
    text-align: center;
    word-break: normal;
    overflow-wrap: break-word;
}

/* Text-flipped state — swap Japanese for English on front face only */
.grid-cards.text-flipped .grid-card-japanese {
    opacity: 0;
    transition: opacity 0.15s ease;
}

.grid-cards.text-flipped .grid-card-english-swap {
    opacity: 1;
}

.grid-cards.text-flipped .grid-card-front .grid-card-romanization {
    display: none;
}

/* =============================================================================
   FRONT-FACE STATUS BUTTONS (Phase 2)
   ============================================================================= */

.grid-card-front-actions {
    display: flex;
    gap: 6px;
    align-items: center;
    z-index: 2;
    position: absolute;
    bottom: 10px;
    right: 12px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
}

.grid-card:hover .grid-card-front-actions {
    opacity: 1;
    pointer-events: auto;
}

/* Status buttons — override global button styles (components.css: shadow, hover lift) */
.grid-card-status-btn,
.grid-card-status-btn:hover,
.grid-card-status-btn:active {
    box-shadow: none;
    transform: none;
}

/* Status buttons — morphing pill: dot at rest, expands with label on hover */
.grid-card-status-btn {
    height: 22px;
    border-radius: 11px;
    border: 1px solid transparent;
    background: transparent;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0;
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 10px;
    font-weight: 400;
    color: #a8a29e;
    opacity: 0.5;
    letter-spacing: 0.02em;
    transition: opacity 0.25s ease, border-color 0.25s ease, background 0.25s ease, color 0.25s ease, padding 0.25s ease, gap 0.25s ease;
    -webkit-tap-highlight-color: transparent;
    flex-shrink: 0;
    padding: 0 4px;
    overflow: hidden;
    white-space: nowrap;
}

/* Dot indicator inside button — colors match left-edge border */
.grid-card-status-btn .status-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex-shrink: 0;
    transition: background 0.25s ease, border-color 0.25s ease;
}

.grid-card-status-btn.known .status-dot {
    background: var(--color-moss);
}

.grid-card-status-btn.learning .status-dot {
    background: transparent;
    border: 1px solid var(--color-amber);
    width: 5px;
    height: 5px;
}

/* Label — hidden by default, revealed on hover */
.grid-card-status-btn .status-label {
    max-width: 0;
    opacity: 0;
    overflow: hidden;
    transition: max-width 0.25s ease, opacity 0.2s ease;
    letter-spacing: 0.01em;
}

/* Default text colors match dot/border colors */
.grid-card-status-btn.known {
    color: var(--color-moss);
}

.grid-card-status-btn.learning {
    color: var(--color-amber);
}

/* Hover: expand to pill with label */
.grid-card:hover .grid-card-status-btn {
    border-color: rgba(44, 44, 44, 0.06);
    opacity: 0.55;
    padding: 0 7px 0 5px;
    gap: 4px;
}

.grid-card:hover .grid-card-status-btn .status-label {
    max-width: 50px;
    opacity: 1;
}

/* Individual button hover */
.grid-card-status-btn.known:hover {
    border-color: rgba(107, 127, 92, 0.25);
    opacity: 0.8;
}

.grid-card-status-btn.learning:hover {
    border-color: rgba(160, 120, 80, 0.25);
    opacity: 0.8;
}

/* Active (selected) state — gentle tint */
.grid-card-status-btn.known.active {
    color: var(--color-moss);
    background: rgba(107, 127, 92, 0.08);
    border-color: rgba(107, 127, 92, 0.25);
    opacity: 0.9;
    padding: 0 7px 0 5px;
    gap: 4px;
}

.grid-card-status-btn.learning.active {
    color: var(--color-amber);
    background: rgba(160, 120, 80, 0.08);
    border-color: rgba(160, 120, 80, 0.25);
    opacity: 0.9;
    padding: 0 7px 0 5px;
    gap: 4px;
}

/* Active buttons always show label (even without card hover) */
.grid-card-status-btn.active .status-label {
    max-width: 50px;
    opacity: 1;
}

/* =============================================================================
   FRONT-FACE STATUS INDICATOR (Desktop) — dot + left-edge earned border
   ============================================================================= */

/* Status dot — top-right, visible at rest, hides on hover as action buttons appear */
.grid-card-front::before {
    content: '';
    position: absolute;
    top: 18px;
    right: 18px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    opacity: 0;
    z-index: 6;
    pointer-events: none;
    transition: opacity 0.25s ease;
}

.grid-card.status-known .grid-card-front::before {
    background: var(--color-moss);
    opacity: 0.7;
}

.grid-card.status-learning .grid-card-front::before {
    background: var(--color-amber);
    opacity: 0.65;
}

/* Hide dot on hover — action buttons take over */
.grid-card:hover .grid-card-front::before {
    opacity: 0;
}

/* Left-edge earned border — inset shadow follows card border-radius naturally */
.grid-card.status-known .grid-card-front {
    box-shadow: inset 3px 0 0 0 rgba(107, 127, 92, 0.45);
}

.grid-card.status-learning .grid-card-front {
    box-shadow: inset 3px 0 0 0 rgba(160, 120, 80, 0.4);
}

/* Sync-triggered status change — subtle settle animation */
@keyframes syncCardSettle {
    0% { opacity: 0.5; transform: translateY(2px); }
    100% { opacity: 1; transform: translateY(0); }
}
.grid-card.sync-status-changed .grid-card-front::before {
    animation: syncCardSettle 400ms ease-out;
}

/* =============================================================================
   BACK-FACE ENRICHED CONTENT (Phase 3)
   ============================================================================= */

/* Header: Japanese text + romanization stacked (reading below word) */
.grid-card-back-header {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 16px 20px 8px;
    padding-right: 60px;  /* Clear space for audio button */
    gap: 2px;
    height: 109px;        /* Fixed height — aligns images across all card types */
    min-height: 109px;
    max-height: 109px;
}

/* Japanese text on back face — dynamic scaling to preserve image space */
.grid-card-back-japanese {
    font-family: 'Klee One', 'Noto Sans JP', sans-serif;
    font-size: clamp(1.1rem, calc(10rem / var(--ja-chars, 5)), 1.6rem);
    font-weight: 600;
    color: #2C2C2C;
    line-height: 1.3;
    white-space: nowrap;
}

/* Larger furigana for readability */
.grid-card-back-japanese rt {
    font-size: 0.65em;
}

/* Romanization on back face — below Japanese text */
.grid-card-back-romanization {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    font-size: 0.8rem;
    font-weight: 400;
    font-style: italic;
    color: #78716c;
}

/* --- Verb forms layout (dict + masu/te) on back face --- */
.grid-verb-forms {
    display: flex;
    align-items: center;
    gap: 0.4em;
}

.grid-verb-dict {
    font-size: 1em;
    font-weight: 600;
    cursor: pointer;
}

.grid-verb-derived {
    display: flex;
    flex-direction: column;
    gap: 0.1em;
    opacity: 0;
    transition: opacity 0.25s ease;
}

.grid-card:hover .grid-verb-derived {
    opacity: 1;
}

.grid-roman-derived {
    opacity: 0;
    transition: opacity 0.25s ease;
}

.grid-card:hover .grid-roman-derived {
    opacity: 1;
}

.grid-verb-masu,
.grid-verb-te {
    font-size: 0.6em;
    font-weight: 400;
    color: #78716c;
    cursor: pointer;
    white-space: nowrap;
}

.grid-verb-dict:hover,
.grid-verb-masu:hover,
.grid-verb-te:hover {
    text-decoration-line: underline;
    text-decoration-style: dotted;
    text-underline-offset: 3px;
}

.grid-verb-dict.playing,
.grid-verb-masu.playing,
.grid-verb-te.playing {
    color: #3D5A80;
}

/* Back-inner wrapper — flex column so image shrinks to fit after header/content */
.grid-card-back-inner {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
    overflow: hidden;
}

/* Back-face status buttons container */
.grid-card-back-actions {
    display: flex;
    gap: 6px;
    align-items: center;
    flex-shrink: 0;
    opacity: 0;
    transition: opacity 0.25s ease;
}

.grid-card:hover .grid-card-back-actions {
    opacity: 1;
}

/* POS tag — hidden in grid view (detail reserved for Focus mode) */
.grid-card-back-pos {
    display: none;
}

/* Focus button — now visible on desktop back face (hover reveal) */

/* Audio button on back face — top-right corner */
.grid-card-back-audio {
    position: absolute;
    top: 14px;
    right: 16px;
    z-index: 5;
    width: 40px;
    height: 40px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: #78716c;
    font-size: 1.1rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    opacity: 0;
    transform: scale(0.92);
    transition: all 0.2s ease, opacity 0.25s ease, transform 0.25s ease;
    -webkit-tap-highlight-color: transparent;
    padding: 0;
}

.grid-card:hover .grid-card-back-audio {
    opacity: 0.7;
    transform: scale(1);
}

.grid-card-back-audio:hover {
    opacity: 1 !important;
    background: rgba(44, 44, 44, 0.04);
}

.grid-card-back-audio:active {
    transform: scale(0.92);
    transition-duration: 0.1s;
}

.grid-card-back-audio.playing {
    animation: audioPulse 1s ease-out;
}

/* Hide old mark buttons overlay — status buttons are on front face now */
.grid-card-actions {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
}

/* =============================================================================
   CARD BACK - CONTENT LAYOUT
   ============================================================================= */

/* Back content area - flex row: English + POS + audio */
.grid-card-back-content {
    flex: 0 0 52px;       /* Fixed footer height — uniform across all cards */
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 12px;
    padding: 0 20px;
    text-align: left;
    position: static;
    z-index: 1;
    overflow: hidden;
}

/* Ensure mark buttons appear above content area */
.grid-card-back .grid-card-actions {
    z-index: 10;
}


/* Large English text on back - single line with unfurl scroll on hover */
.grid-card-english-large {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    font-size: 1.1rem;
    font-weight: 500;
    color: #57534e;
    line-height: 1.4;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: left;
    letter-spacing: -0.01em;
    flex: 1;
    min-width: 0;         /* Allow flex child to shrink below content size */
}

/* Inline Unfurl — horizontal scroll on hover for truncated text */
.unfurl-wrap {
    overflow: hidden;
    width: 100%;
    mask-image: linear-gradient(to right, black 88%, transparent 100%);
    -webkit-mask-image: linear-gradient(to right, black 88%, transparent 100%);
}

.unfurl-wrap.unfurling {
    mask-image: linear-gradient(to right, transparent 0%, black 3%, black 97%, transparent 100%);
    -webkit-mask-image: linear-gradient(to right, transparent 0%, black 3%, black 97%, transparent 100%);
}

.unfurl-text {
    display: inline-block;
    white-space: nowrap;
}

/* POS tag - hidden in grid view (shown in Focus mode only) */
.grid-card-pos {
    display: none !important;
}

/* Mark buttons on back - hidden until hover, positioned individually */
.grid-card-actions {
    position: absolute;
    inset: 0;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    padding: 12px;
    opacity: 0;
    z-index: 20;
    pointer-events: none;
    transition: opacity var(--grid-transition-medium) var(--ease-out-expo);
}

/* Known button - top left */
.grid-card-actions .grid-card-mark-btn.known {
    align-self: flex-start;
}

/* Learning button - top right */
.grid-card-actions .grid-card-mark-btn.learning {
    align-self: flex-start;
}

.grid-card-actions .grid-card-mark-btn {
    transform: translateY(8px);
    pointer-events: auto;
    transition:
        transform var(--grid-transition-medium) var(--ease-out-back),
        box-shadow var(--grid-transition-fast) ease,
        background var(--grid-transition-fast) ease;
}

/* Show mark buttons on flipped card hover (desktop 3D flip) */
.grid-card.flipped:hover .grid-card-actions {
    opacity: 1;
    transition: opacity 0.12s ease-out;
}

.grid-card.flipped:hover .grid-card-actions .grid-card-mark-btn {
    transform: translateY(0);
    transition-delay: 0.1s;
    transition-duration: 0.15s;
}

/* =============================================================================
   MOBILE STYLES (≤768px)
   ============================================================================= */

/* =============================================================================
   EMPTY STATE — 余白 (Yohaku) Minimalist
   ============================================================================= */

@keyframes emptyFadeIn {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.grid-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 50vh;
    text-align: center;
    padding: 64px 40px;
    animation: emptyFadeIn 0.8s ease-out;
}

.grid-empty-icon {
    margin-bottom: 32px;
    color: #a8a29e;
    opacity: 0.7;
}

.grid-empty-icon svg {
    width: 48px;
    height: 48px;
}

.grid-empty-text {
    font-family: 'Klee One', 'Noto Sans JP', sans-serif;
    font-size: 1.3rem;
    font-weight: 400;
    color: #57534e;
    margin-bottom: 12px;
    letter-spacing: 0.02em;
}

.grid-empty-hint {
    font-family: 'Inter', sans-serif;
    font-size: 0.85rem;
    font-weight: 400;
    color: #a8a29e;
    max-width: 280px;
    line-height: 1.6;
}

/* First-visit welcome variant */
.grid-empty-welcome {
    font-family: 'Klee One', 'Noto Sans JP', sans-serif;
    font-size: 1.1rem;
    color: #78716c;
    margin-top: 16px;
    padding: 12px 20px;
    background: rgba(201, 169, 110, 0.06);
    border-radius: 12px;
    border: 1px solid rgba(201, 169, 110, 0.12);
}

/* =============================================================================
   折り目 (Orime) — Crease of Use
   Cards with mastery data show visual aging
   ============================================================================= */

body:not(.video-mode) [data-orime="warm"] {
    border-color: rgba(201, 169, 110, 0.15);
}

body:not(.video-mode) [data-orime="fold"] {
    position: relative;
}

body:not(.video-mode) [data-orime="fold"]::after {
    content: '';
    position: absolute;
    left: 8%;
    right: 8%;
    top: 50%;
    height: 1px;
    background: rgba(201, 169, 110, 0.04);
    pointer-events: none;
    z-index: 1;
}

body:not(.video-mode) [data-orime="mastered"] {
    position: relative;
}

body:not(.video-mode) [data-orime="mastered"]::after {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 20px 20px 0;
    border-color: transparent rgba(201, 169, 110, 0.12) transparent transparent;
    pointer-events: none;
    z-index: 1;
}

/* =============================================================================
   END-OF-LIST FOOTER
   ============================================================================= */

.grid-end-footer {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 32px 16px;
}

.grid-end-top-btn {
    padding: 8px 20px;
    border-radius: var(--radius-pill, 999px);
    border: 1px solid rgba(44, 44, 44, 0.08);
    background: var(--card-surface, #FAFAF7);
    color: var(--text-secondary, #57534e);
    font-family: 'Inter', sans-serif;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.grid-end-top-btn:hover {
    background: rgba(140, 133, 120, 0.06);
    border-color: rgba(44, 44, 44, 0.12);
    transform: translateY(-1px);
}

.grid-end-top-btn:active {
    transform: translateY(0) scale(0.97);
}

/* =============================================================================
   +MORE CARD — batch continuation in Learn/Review queue
   ============================================================================= */

.grid-more-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    background: var(--card-surface, #FAFAF7);
    border-radius: 14px;
    border: 1px solid rgba(44, 44, 44, 0.06);
    box-shadow: 0 1px 3px rgba(44, 44, 44, 0.03);
    cursor: pointer;
    transition: border-color 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
    animation: cardEntrance 0.6s var(--ease-out-expo) backwards;
    min-height: 200px;
    position: relative;
    overflow: hidden;
}

.grid-more-card:hover {
    border-color: rgba(61, 90, 128, 0.15);
    transform: translateY(-1px);
    box-shadow: 0 2px 8px rgba(44, 44, 44, 0.05);
}

.grid-more-card:hover .grid-more-corner {
    width: 40px;
    height: 40px;
}

.grid-more-card:active {
    transform: translateY(0) scale(0.98);
}

/* Page-turn corner */
.grid-more-corner {
    position: absolute;
    top: 0;
    right: 0;
    width: 36px;
    height: 36px;
    background: linear-gradient(225deg, var(--body-bg, #F0EDE8) 50%, transparent 50%);
    border-bottom-left-radius: 6px;
    border-bottom: 1px solid rgba(44, 44, 44, 0.04);
    border-left: 1px solid rgba(44, 44, 44, 0.04);
    transition: width 0.25s ease, height 0.25s ease;
}

.grid-more-jp {
    font-family: 'Klee One', serif;
    font-size: 32px;
    color: var(--text-primary, #2C2C2C);
    letter-spacing: 0.04em;
}

.grid-more-jp rt {
    font-family: 'Noto Sans JP', sans-serif;
    font-size: 11px;
    color: var(--text-secondary, #57534e);
    font-weight: 400;
}

.grid-more-translation {
    font-family: 'Inter', sans-serif;
    font-size: 13px;
    color: var(--text-secondary, #57534e);
    opacity: 0.45;
    font-style: italic;
}

.grid-more-count {
    font-family: 'Inter', sans-serif;
    font-size: 13px;
    color: var(--text-secondary, #57534e);
    opacity: 0.6;
    margin-top: 4px;
}

/* Progress bar */
.grid-more-progress {
    width: 80px;
    height: 3px;
    background: rgba(44, 44, 44, 0.06);
    border-radius: 2px;
    overflow: hidden;
}

.grid-more-progress-fill {
    height: 100%;
    background: var(--accent, #3D5A80);
    opacity: 0.35;
    border-radius: 2px;
}

/* =============================================================================
   LOADING STATE - Enhanced Skeleton
   ============================================================================= */

.grid-card.loading {
    pointer-events: none;
    overflow: hidden;
}

.grid-card.loading::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
        90deg,
        rgba(255, 255, 255, 0.08) 25%,
        rgba(255, 255, 255, 0.18) 50%,
        rgba(255, 255, 255, 0.08) 75%
    );
    background-size: 200% 100%;
    animation: shimmer 1.8s ease-in-out infinite;
}

.grid-card.loading .grid-card-image {
    background: rgba(148, 163, 184, 0.06);
}

.grid-card.loading .grid-card-content {
    background: transparent;
}

.grid-card.loading .grid-card-japanese,
.grid-card.loading .grid-card-romanization {
    background: rgba(148, 163, 184, 0.12);
    border-radius: 6px;
    color: transparent !important;
    min-height: 1.5em;
}

/* Status indication via card-level classes and status bar */

/* =============================================================================
   ACTION BAR - HIDE IN GRID MODE
   ============================================================================= */

/* Hide the entire action bar in grid mode */
body.grid-mode .bottom-action-bar {
    display: none !important;
}

/* =============================================================================
   PREMIUM POLISH - DESKTOP ENHANCEMENTS
   Only apply scroll-aware animations on desktop (causes issues on mobile)
   ============================================================================= */

@media (min-width: 769px) {
    /* 1. Scroll-aware card entrance - cards animate when first scrolling into view */
    .grid-card:not(.in-view) {
        opacity: 0;
        transform: translateY(12px);
        animation: none;
    }

    .grid-card.in-view {
        animation: cardEntrance 0.6s var(--ease-out-expo) forwards;
    }
}

/* Focus button — no ambient glow (和の感性: scarcity gives meaning) */

/* 3. English text reveal animation on back face */
@keyframes textReveal {
    from {
        opacity: 0;
        transform: translateY(10px);
        filter: blur(4px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
        filter: blur(0);
    }
}

.grid-card.flipped .grid-card-english-large {
    animation: textReveal 0.4s ease-out 0.15s backwards;
}

/* =============================================================================
   PREMIUM POLISH - AUDIO PLAYING EFFECTS
   ============================================================================= */

/* Audio button enhanced state while playing */
.grid-card-audio.playing {
    background: #3D5A80;
    box-shadow:
        0 4px 16px rgba(61, 90, 128, 0.3),
        0 0 0 4px rgba(61, 90, 128, 0.12);
    transform: scale(1.1);
    transition: background-color 0.2s ease-out, box-shadow 0.2s ease-out, transform 0.2s ease-out;
}

/* Sound wave rings - use pseudo-elements with opacity control */
.grid-card-audio::before,
.grid-card-audio::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 2px solid rgba(61, 90, 128, 0.5);
    opacity: 0;
    pointer-events: none;
}

@keyframes soundWaveRing {
    0% {
        transform: scale(1);
        opacity: 0.6;
    }
    100% {
        transform: scale(2.2);
        opacity: 0;
    }
}

.grid-card-audio.playing::before {
    animation: soundWaveRing 1.2s ease-out infinite;
}

.grid-card-audio.playing::after {
    animation: soundWaveRing 1.2s ease-out 0.4s infinite;
}

/* Fade out: stop new waves, let existing ones finish naturally */
.grid-card-audio.fade-out {
    background: var(--grid-audio-btn);
    box-shadow: 0 2px 8px rgba(61, 90, 128, 0.18);
    transform: scale(1);
    transition: background-color 0.3s ease-out, box-shadow 0.3s ease-out, transform 0.3s ease-out;
}

.grid-card-audio.fade-out::before,
.grid-card-audio.fade-out::after {
    animation: none;
    opacity: 0;
    transition: opacity 0.2s ease-out;
}

/* Japanese text glow - use transform for GPU acceleration */
.grid-card.audio-playing .grid-card-japanese {
    text-shadow:
        0 0 8px rgba(61, 90, 128, 0.24),
        0 0 16px rgba(61, 90, 128, 0.12);
    transition: text-shadow 0.3s ease-out;
}

/* Fade out: smooth return to resting ink diffusion */
.grid-card.audio-fade-out .grid-card-japanese,
.grid-card:not(.audio-playing) .grid-card-japanese {
    text-shadow: 0 0 0.5px rgba(44, 44, 44, 0.12);  /* Resting ink absorption */
    transition: text-shadow 0.3s ease-out;
}

/* Card glow effect (desktop only) - static glow, not animated */
@media (min-width: 769px) {
    .grid-card.audio-playing {
        box-shadow:
            var(--grid-card-shadow),
            0 0 25px rgba(61, 90, 128, 0.09);
        transition: box-shadow 0.3s ease-out;
    }

    .grid-card.audio-fade-out,
    .grid-card:not(.audio-playing) {
        transition: box-shadow 0.3s ease-out;
    }
}

/* =============================================================================
   PREMIUM POLISH - MOBILE ENHANCEMENTS
   ============================================================================= */

/* =============================================================================
   REDUCED MOTION - Grid-specific accessibility
   Replaces 3D flip with opacity crossfade, disables accordion animation
   ============================================================================= */
@media (prefers-reduced-motion: reduce) {
    /* Disable 3D flip — use opacity crossfade instead */
    .grid-card {
        perspective: none;
    }

    .grid-card-inner {
        transform-style: flat;
        transition: none;
    }

    .grid-card.flipped .grid-card-inner {
        transform: none;
    }

    .grid-card-front,
    .grid-card-back {
        backface-visibility: visible;
        transform: none;
    }

    .grid-card-front {
        opacity: 1;
        transition: opacity 0.01ms;
    }

    .grid-card.flipped .grid-card-front {
        opacity: 0;
    }

    .grid-card-back {
        opacity: 0;
        transform: none;
    }

    .grid-card.flipped .grid-card-back {
        opacity: 1;
    }

    /* Disable flip pulse animation */
    .grid-card.flipping .grid-card-inner {
        animation: none;
    }

    /* Disable accordion expand/collapse animation (mobile) */
    .grid-card.expanded {
        transition: none;
    }

    .grid-card-back {
        transition: none !important;
    }

    /* Disable hover lift */
    .grid-card:hover {
        transform: none;
    }

}

/* =============================================================================
   WORD STORY SHOJI PANEL
   ============================================================================= */

/* Story button — three-dot reveal, next to audio button */
.grid-card-story-btn {
    position: absolute;
    top: 14px;
    right: 62px;
    z-index: 5;
    width: 40px;
    height: 40px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: #78716c;
    font-size: 18px;
    letter-spacing: 2px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    opacity: 0;
    transform: scale(0.92);
    transition: all 0.2s ease, opacity 0.25s ease, transform 0.25s ease;
    -webkit-tap-highlight-color: transparent;
    padding: 0 0 0 2px;
}

.grid-card:hover .grid-card-story-btn {
    opacity: 0.7;
    transform: scale(1);
}

.grid-card-story-btn:hover {
    opacity: 1 !important;
    background: rgba(44, 44, 44, 0.04);
}

.grid-card-story-btn:active {
    transform: scale(0.92);
    transition-duration: 0.1s;
}

/* Active state when panel is open */
.grid-card.shoji-active .grid-card-story-btn {
    opacity: 1 !important;
    background: rgba(44, 44, 44, 0.06);
}

/* Keep the audio + focus buttons revealed too while the shoji panel is open
   — otherwise hover-out hides them while the story button stays pinned,
   leaving a lonely ⋯ next to an empty top-right corner. */
.grid-card.shoji-active .grid-card-back-audio,
.grid-card.shoji-active .grid-card-focus-btn {
    opacity: 0.7;
    transform: scale(1);
}

/* Shoji panel — slides up below header */
.grid-story-panel {
    position: absolute;
    top: 109px;   /* Flush with image top (back-header height) */
    bottom: 38px; /* Above peek strip (grid-card-rel height) */
    left: 0;
    right: 0;
    background: #FEFDFB;
    z-index: 15;
    padding: 20px 24px 16px;
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateY(100%);
    opacity: 0;
    transition: transform 300ms cubic-bezier(0.22, 1, 0.36, 1),
                opacity 150ms ease;
    border-radius: 0;
}

/* Inherit left-edge earned border from card status */
.grid-card-back.known .grid-story-panel {
    box-shadow: inset 3px 0 0 0 rgba(107, 127, 92, 0.45);
}

.grid-card-back.learning .grid-story-panel {
    box-shadow: inset 3px 0 0 0 rgba(160, 120, 80, 0.4);
}

/* Top hairline separator */
.grid-story-panel::before {
    content: '';
    position: absolute;
    top: 0;
    left: 16px;
    right: 16px;
    height: 1px;
    background: rgba(44, 44, 44, 0.06);
}

.grid-card.shoji-active .grid-story-panel {
    transform: translateY(0);
    opacity: 1;
}

/* Section spacing with hairline dividers */
.grid-story-section + .grid-story-section {
    padding-top: 14px;
    border-top: 1px solid rgba(44, 44, 44, 0.04);
    margin-top: 14px;
}

/* Section label — quiet wayfinding */
.grid-story-label {
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: #78716c;
    margin-bottom: 6px;
}

/* Section text — readable body */
.grid-story-text {
    font-size: 13.5px;
    line-height: 1.6;
    color: #44403c;
}

.grid-story-text strong {
    color: #2C2C2C;
    font-weight: 600;
}

/* Example sentences in shoji panel */
.grid-story-example {
    padding: 8px 0;
}

.grid-story-example + .grid-story-example {
    border-top: 1px solid rgba(44, 44, 44, 0.03);
}

.grid-story-example-jp {
    font-family: 'Klee One', 'Noto Sans JP', sans-serif;
    font-size: 14px;
    line-height: 1.7;
    color: #2C2C2C;
}

.grid-story-example-romaji {
    font-size: 12px;
    line-height: 1.5;
    color: #a8a29e;
    margin-top: 1px;
    font-style: italic;
}

.grid-story-example-en {
    font-size: 12.5px;
    line-height: 1.5;
    color: #78716c;
    margin-top: 1px;
}

/* Counter list in shoji panel (compact, collapsible) */
.grid-counter-list {
    display: flex;
    flex-direction: column;
}
.grid-counter-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 2px;
    border-radius: 6px;
}
.grid-counter-num {
    font-size: 10px;
    font-weight: 500;
    color: #a8a29e;
    opacity: 0.5;
    min-width: 16px;
    text-align: right;
    flex-shrink: 0;
}
.grid-counter-jp {
    font-family: 'Klee One', 'Noto Sans JP', sans-serif;
    font-size: 15px;
    font-weight: 600;
    color: #2C2C2C;
    line-height: 1.4;
    letter-spacing: 0.02em;
    flex: 1;
    min-width: 0;
}
.grid-counter-jp rt {
    font-size: max(0.5em, 8px);
    color: #a8a29e;
    font-weight: 400;
    letter-spacing: 0.05em;
}
.grid-counter-reading {
    font-family: Inter, sans-serif;
    font-size: 12px;
    font-style: italic;
    color: #a8a29e;
    letter-spacing: 0.02em;
    flex-shrink: 0;
}
.grid-counter-audio-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    border: 1px solid rgba(44, 44, 44, 0.06);
    border-radius: 50%;
    background: transparent;
    color: #a8a29e;
    opacity: 0.4;
    cursor: pointer;
    padding: 0;
}
.grid-counter-audio-btn:active,
.grid-counter-audio-btn.playing { opacity: 1; color: #C9A96E; }
.grid-counter-question {
    border-top: 1px solid rgba(201, 169, 110, 0.15);
    margin-top: 2px;
    padding-top: 6px;
}
.grid-counter-question .grid-counter-num {
    color: #C9A96E;
    opacity: 0.7;
    font-weight: 600;
}
.grid-counter-question .grid-counter-reading {
    color: #C9A96E;
    opacity: 0.6;
}
/* Collapse/expand */
.grid-counter-more {
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    transition: max-height 0.25s ease-out, opacity 0.2s ease-out;
}
.grid-counter-more.expanded {
    max-height: 600px;
    opacity: 1;
}
.grid-counter-toggle {
    padding: 6px 2px;
    cursor: pointer;
    text-align: center;
}
.grid-counter-toggle-text {
    font-family: Inter, sans-serif;
    font-size: 11px;
    font-style: italic;
    color: #a8a29e;
    opacity: 0.6;
    transition: opacity 0.15s ease;
}
.grid-counter-toggle:hover .grid-counter-toggle-text {
    opacity: 1;
}

/* Scrollbar — subtle */
.grid-story-panel::-webkit-scrollbar {
    width: 4px;
}

.grid-story-panel::-webkit-scrollbar-thumb {
    background: rgba(44, 44, 44, 0.1);
    border-radius: 2px;
}



/* =============================================================================
   WORD RELATIONSHIPS — In-place Drawer (和の感性)
   The "N related" button now lives inline in .grid-card-meta-row
   (css/freq-tier.css), not as a separate peek strip. Styles for the inline
   button are colocated with the meta row. The expand-panel below stays here.
   ============================================================================= */

/* ---------- Related Words — Slide-out Panel Below Card ---------- */

/* Visual marker on the open card — flatten bottom corners so panel joins seamlessly */
.grid-card.rel-open {
    z-index: 10;
    border-radius: 14px 14px 0 0;
}

/* Panel floats in .grid-container (outside card's preserve-3d context).
   Styled to look like a seamless extension of the card (matching Concept C drawer). */
.rel-expand-panel {
    background: var(--card-surface, #FAFAF7);
    border-radius: 0 0 14px 14px;
    box-shadow: 0 2px 8px rgba(44, 44, 44, 0.06), 0 1px 2px rgba(44, 44, 44, 0.04);
    padding: 12px 16px 16px;
    max-height: 280px;
    overflow-y: auto;
    opacity: 0;
    transform: translateY(-6px);
    /* Close transition: softer, slightly longer ease-out */
    transition: opacity 0.3s ease-out,
                transform 0.3s ease-out;
    pointer-events: none;
    z-index: 50;
    border: 1px solid rgba(44, 44, 44, 0.05);
    border-top: none;
}

.rel-expand-panel.rel-panel-visible {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
    /* Open transition: snappy spring */
    transition: opacity 0.25s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

/* Drag handle — hidden */
.rel-drawer-handle {
    display: none;
}

/* Cards below in same column get pushed — via JS margin-top */
/* B8-1: margin-top transition merged into base .grid-card rule to avoid overwrite */

/* Group label — uppercase, small — always visible */
.rel-group-label {
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-tertiary, #8C8578);
    margin-bottom: 6px;
    padding-left: 2px;
}

/* Divider between groups */
.rel-divider {
    height: 1px;
    background: rgba(44, 44, 44, 0.04);
    margin: 10px 4px;
}

/* Hide first divider */
.rel-group:first-child + .rel-divider {
    /* keep visible */
}

/* Word row — two-row layout: dot + body */
.rel-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 8px;
    border-radius: 8px;
    cursor: pointer;
    transition: background 150ms ease;
}

.rel-row:hover {
    background: rgba(44, 44, 44, 0.025);
}

/* Display-only variant — used inside grid-mode dropdown where the row
   shouldn't navigate. Keeps the audio button inside fully interactive. */
.rel-row--display {
    cursor: default;
}
.rel-row--display:hover {
    background: transparent;
}

/* Colored dot — vertically centered against the two rows */
.rel-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
}

.rel-dot--synonym   { background: var(--color-moss-bright); }
.rel-dot--antonym   { background: var(--color-coral); }
.rel-dot--homophone { background: #C9A96E; }
.rel-dot--homograph { background: #8B6F47; }
.rel-dot--related   { background: #3D5A80; }

/* Body wraps both rows, fills remaining width */
.rel-row-body {
    flex: 1;
    min-width: 0;
}

/* Top row: kanji (left) + english (right) */
.rel-row-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.rel-row-kanji {
    font-family: 'Klee One', serif;
    font-size: 22px;
    font-weight: 600;
    color: var(--text-primary, #2C2C2C);
    line-height: 1.2;
}

.rel-row-en {
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 13px;
    color: var(--text-secondary, #57534e);
    text-align: right;
    flex-shrink: 0;
    margin-left: auto;
}

/* Audio button — appears on hover, sits between kanji and english */
.rel-row-audio {
    border: none;
    background: none;
    box-shadow: none;
    padding: 2px 6px;
    cursor: pointer;
    font-size: 10px;
    color: var(--text-tertiary, #8C8578);
    opacity: 0;
    transition: opacity 200ms ease, color 200ms ease;
    flex-shrink: 0;
}

.rel-row:hover .rel-row-audio {
    opacity: 0.6;
}

.rel-row-audio:hover {
    opacity: 1 !important;
    color: var(--text-primary, #2C2C2C);
    transform: none;
    box-shadow: none;
}

.rel-row-audio:active {
    transform: none;
}

/* Sub row: kana · romanization */
.rel-row-sub {
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 12px;
    color: var(--text-tertiary, #8C8578);
    margin-top: 2px;
    letter-spacing: 0.01em;
}

/* Highlight flash when navigating to a related card */
@keyframes relHighlight {
    0% { box-shadow: 0 0 0 3px rgba(201, 169, 110, 0.5); }
    100% { box-shadow: 0 0 0 3px rgba(201, 169, 110, 0); }
}

.grid-card.rel-highlight {
    animation: relHighlight 1.5s ease-out;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .rel-expand-panel {
        transition: none;
    }
    .grid-card.rel-highlight {
        animation: none;
        box-shadow: 0 0 0 3px rgba(201, 169, 110, 0.3);
    }
}
