/* rusty begin new code | 2026-09-02 16:49 */
/* Action: Homepage-scoped stylesheet for the UX/UI overhaul. Owns the --home-* token
   set (one spacing scale, one radius scale, one desaturated border), the global
   reduced-motion collapse, the refactored hero, and the 1+4 feature grid.
   Loaded via index.blade.php @section('style') so it lands last in <head> and wins
   specificity ties against style.css and macblash-site-theme.css.
   Scoped with .page-bg (the @yield('content') wrapper) so nothing leaks to other pages. */

/* ============================================================================
   1. TOKENS
   Spacing/radii/shadows were never tokenised in this project (literal 50px 0,
   10px/20px/50px radii scattered across two stylesheets). These four tokens are
   consumed by the hero, all three feature grids, and the section rhythm.
   ========================================================================= */
:root {
    --home-section-py: clamp(3.5rem, 8vw, 6rem);
    /* one vertical rhythm, density 4 */
    --home-gap: 1.25rem;
    --home-radius: 14px;
    /* SHAPE CONSISTENCY LOCK */
    --home-border-color: rgba(139, 92, 246, .22);
    /* desaturated from --cyber-border (.4) */
    --home-border: 1px solid var(--home-border-color);
    --home-scrim: linear-gradient(90deg, rgba(5, 5, 8, .82) 0%, rgba(5, 5, 8, .55) 45%, rgba(5, 5, 8, 0) 100%);
    --home-ease: cubic-bezier(.16, 1, .3, 1);
}

/* ============================================================================
   2. REDUCED MOTION
   The homepage carries several infinite loops (gradient text flow, pulse dots,
   digital rain, hologram drift) that had no prefers-reduced-motion guard at all.
   Collapse them to static here rather than per-component.
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {

    .page-bg .animate-gradient,
    .page-bg .animate-pulse,
    .page-bg .digital-rain,
    .page-bg .hologram-effect,
    .page-bg .hero-title-accent {
        animation: none !important;
        transition: none !important;
    }

    /* Gradient-clipped text has no readable fallback once the animation stops,
       so give it a flat accent fill. */
    .page-bg .hero-title-accent {
        background: none !important;
        -webkit-background-clip: initial !important;
        background-clip: initial !important;
        -webkit-text-fill-color: var(--cyber-cyan) !important;
        color: var(--cyber-cyan) !important;
    }
}

/* rusty end new code */


/* rusty begin new code | 2026-09-02 16:49 */
/* Action: Hero refactor styles. The headline block is a static overlay stacked on the
   swiper via CSS Grid overlap, so only the image and caption transition.
   Logical properties throughout (inset-inline-*, justify-self) so RTL and LTR both work
   from one rule set: in RTL `start` resolves to the right, which preserves the original
   text-on-the-right composition. */

/* ── Section shell ─────────────────────────────────────────────────────────── */
/* rusty begin update | 2026-09-02 22:45 */
/* Action: dropped min-height: 100dvh and cut padding-block. The full-viewport hero left
   a tall empty gap between the slider and the ticker; now the section hugs the slider
   (which carries its own clamp() height) with only a small band of breathing room. */
.hero-cyber {
    display: flex;
    align-items: center;
    justify-content: center;
    /* Bottom padding is 0 so the ticker's 4px margin is the entire gap under the hero. */
    padding-block: clamp(1rem, 3vh, 2rem) 0;
    background: transparent;
}

/* rusty end update */

.hero-cyber-bg {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

/* ── Grid overlap: swiper and static stack share one cell ──────────────────── */
.hero-cyber-grid {
    display: grid;
    position: relative;
    z-index: 10;
    width: 100%;
    max-width: 1280px;
    margin-inline: auto;
    padding-inline: clamp(1rem, 3vw, 2rem);
}

.hero-cyber-grid>* {
    grid-area: 1 / 1;
}

/* ── (A) The part that moves ───────────────────────────────────────────────── */
.hero-cyber-swiper {
    position: relative;
    border-radius: 1.5rem;
    overflow: hidden;
}

.hero-cyber-swiper .swiper-slide {
    position: relative;
    /* anchor for .hero-slide-caption */
}

/* rusty begin update | 2026-09-16 14:45 */
/* Action: object-fit cover -> contain so an uploaded slide is never cropped and never
   stretched. cover filled the fixed clamp() box by cutting away whatever overflowed:
   the current 1376x768 upload (aspect 1.79) against a ~1.71 box lost a slice off both
   side edges, which is the reported "image overlaps / gets cut at the edges".
   contain on its own would leave dead letterbox bars, so .hero-slide-img-fill paints a
   blurred, slightly scaled copy of the same file behind it to fill them.
   The clamp() height moves to the wrapper, so the box height is unchanged and the
   overlaid .hero-cyber-stack headline keeps its exact position between slides. */
.hero-slide-media {
    position: relative;
    width: 100%;
    height: clamp(450px, 75vh, 750px);
    overflow: hidden;
    background: #05050a;
}

.hero-slide-img-fill {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* scale() hides the soft transparent edge a blur leaves at the element boundary */
    transform: scale(1.12);
    filter: blur(28px) saturate(135%);
    pointer-events: none;
}

.hero-slide-img {
    position: relative;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}
/* rusty end update */

/* Caption sits opposite the static stack so the two never collide. */
.hero-slide-caption {
    position: absolute;
    inset-inline-end: clamp(1rem, 3vw, 2.25rem);
    inset-block-end: 3.25rem;
    max-width: 32ch;
    margin: 0;
    padding: .65rem .9rem;
    border-radius: var(--home-radius);
    background: rgba(5, 5, 8, .55);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    color: #f1f5f9;
    font-size: 1rem;
    line-height: 1.6;
    text-align: start;
}

/* Swiper controls must sit above the overlay scrim and stay clickable. */
.hero-cyber-swiper .swiper-button-next,
.hero-cyber-swiper .swiper-button-prev,
.hero-cyber-swiper .swiper-pagination {
    z-index: 20;
    pointer-events: auto;
}

/* rusty begin update | 2026-09-03 03:40 */
/* Action: pagination floats inside the image area and stays out of the way until the
   visitor actually engages with the slider. Hidden by default, revealed on hover or
   touch, faded back out 1s after the interaction ends (timer lives in macblash-fx.js).
   :focus-within is included so keyboard users can see which bullet is active - without
   it the dots would be permanently invisible to them. */
.hero-cyber-swiper .swiper-pagination {
    position: absolute;
    bottom: 20px;
    z-index: 20;
    opacity: 0;
    transition: opacity .4s ease;
}

.hero-cyber-swiper .swiper-pagination.is-visible,
.hero-cyber-swiper:focus-within .swiper-pagination {
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    .hero-cyber-swiper .swiper-pagination {
        transition: none;
    }
}
/* rusty end update */

/* ── (B) The part that stays ───────────────────────────────────────────────── */
/* rusty begin update | 2026-09-02 22:45 */
/* Action: shrunk the overlay so it no longer blocks the slider artwork. The heavy
   --home-scrim panel is gone; legibility now comes from a very soft radial pool anchored
   to the inline-start corner plus text-shadow on the headline. Box is content-sized
   (max-width cap only) with tight padding instead of a fixed 38rem/54% slab. */
.hero-cyber-stack {
    align-self: center;
    justify-self: start;
    /* RTL -> right, LTR -> left */
    z-index: 15;
    width: auto;
    max-width: min(30rem, 46%);
    padding: clamp(.6rem, 1.6vw, 1.1rem) clamp(.85rem, 2vw, 1.4rem);
    border-radius: var(--home-radius);
    /* Tight, low-alpha pool - fades out well before the image edges. */
    background: radial-gradient(120% 130% at 0% 50%, rgba(5, 5, 8, .42) 0%, rgba(5, 5, 8, 0) 68%);
    text-align: start;
    pointer-events: none;
    /* never swallow swiper drag / arrows / bullets */
    /* rusty begin update | 2026-09-03 04:10 */
    /* Action: drives the 30-second idle fade below. */
    transition: opacity .5s ease;
    /* rusty end update */
}

/* rusty end update */

/* rusty begin new code | 2026-09-03 04:10 */
/* Action: IDLE MODE. macblash-fx.js adds .idle-mode to the stack 30 seconds after load,
   so a visitor who leaves the homepage open eventually gets an unobstructed view of the
   slider artwork. Hovering the hero brings it straight back.

   Desktop only, and gated by the MEDIA QUERY rather than by a width check in JS: the
   class is added unconditionally, so a tablet rotated into landscape starts obeying the
   idle rules immediately instead of being stuck with whatever the viewport was at load.

   Note what is NOT restored on hover: pointer-events on the stack itself. It is
   permanently `none` by design so a drag starting over the headline still reaches the
   swiper underneath; only the CTAs toggle, which is what actually needs to stop being
   clickable while the stack is invisible.

   :focus-within is paired with :hover throughout, otherwise a keyboard user tabbing to
   a CTA would be focusing something they cannot see. */
@media (min-width: 992px) {

    .hero-cyber-stack.idle-mode {
        opacity: 0;
    }

    .hero-cyber-stack.idle-mode .hero-cta {
        pointer-events: none;
    }

    .hero-cyber-grid:hover .hero-cyber-stack.idle-mode,
    .hero-cyber-grid:focus-within .hero-cyber-stack.idle-mode {
        opacity: 1;
    }

    .hero-cyber-grid:hover .hero-cyber-stack.idle-mode .hero-cta,
    .hero-cyber-grid:focus-within .hero-cyber-stack.idle-mode .hero-cta {
        pointer-events: auto;
    }
}

@media (prefers-reduced-motion: reduce) {
    .hero-cyber-stack {
        transition: none;
    }
}
/* rusty end new code */

/* Only the buttons capture the pointer. Leaving the headline/eyebrow inert means a
   drag that starts over the text still reaches the swiper underneath. */
.hero-cyber-stack .hero-cta {
    pointer-events: auto;
}

/* rusty begin delete | 2026-09-02 22:45 */
/* Action: removed the .hero-eyebrow / .hero-eyebrow-dot rules and the hero-dot-pulse
   keyframe. The "Status: Cyber-Market Online" eyebrow span was deleted from
   index.blade.php (static filler copy), so these selectors now match nothing.
   Recoverable from git history. CRITICAL-HERO-01
   2026-09-03 00:50: the trailing .hero-eyebrow-dot entries have now been dropped from the
   two prefers-reduced-motion selector lists as well, so no reference to the eyebrow
   remains anywhere in this stylesheet. */
/* rusty end delete */

.hero-title {
    margin: 0;
    font-family: 'Sukar', sans-serif;
    font-weight: 900;
    font-size: clamp(2.5rem, 5.5vw, 4.5rem);
    line-height: 1.12;
    color: #fff;
    /* rusty begin update | 2026-09-02 22:45 */
    /* Action: carries legibility now that the scrim panel is gone - keeps the white
       headline readable over a bright slide without a box behind it. */
    text-shadow: 0 2px 10px rgba(0, 0, 0, .55), 0 1px 3px rgba(0, 0, 0, .7);
    /* rusty end update */
}

/* rusty begin new code | 2026-09-03 00:20 */
/* Action: the headline is now two admin-configurable parts (main + accent), each with its
   own font-size, so they must be block-level to stack - this replaces the old hardcoded
   <br> between them. The admin's px value is only the CEILING of a clamp(), and these
   wrap rules are the second half of the mobile safety net: a long headline, or one very
   long unbroken word, breaks inside the stack instead of pushing the hero sideways. */
.hero-title-part {
    display: block;
    min-width: 0;
    word-break: break-word;
    overflow-wrap: anywhere;
}
/* rusty end new code */

.hero-title-accent {
    background-image: linear-gradient(90deg, var(--cyber-purple), var(--cyber-cyan), var(--cyber-purple));
    background-size: 200% auto;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    animation: hero-title-flow 6s linear infinite;
}

@keyframes hero-title-flow {
    to {
        background-position: 200% center;
    }
}

/* ── CTAs ──────────────────────────────────────────────────────────────────── */
.hero-cta-row {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    margin-block-start: 1.75rem;
}

/* One radius scale across the page (SKILL.md 4.4 SHAPE CONSISTENCY LOCK). The old
   skewX(-12deg) parallelogram buttons with counter-skewed inner spans are retired. */
.hero-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: .9rem 1.9rem;
    border-radius: var(--home-radius);
    font-weight: 800;
    font-size: 1.05rem;
    white-space: nowrap;
    /* SKILL.md 4.5: CTA never wraps at desktop */
    text-decoration: none;
    transition: transform .25s var(--home-ease), background .25s var(--home-ease),
        border-color .25s var(--home-ease), color .25s var(--home-ease);
}

.hero-cta-primary {
    background: var(--cyber-cyan);
    border: 1px solid var(--cyber-cyan);
    color: #04141a;
    /* AA contrast on cyan, not pure black */
}

.hero-cta-secondary {
    background: rgba(139, 92, 246, .08);
    border: 1px solid rgba(139, 92, 246, .55);
    color: #fff;
}

.hero-cta:hover,
.hero-cta:focus-visible {
    transform: translateY(-2px);
}

.hero-cta-primary:hover,
.hero-cta-primary:focus-visible {
    background: #22d3ee;
    color: #04141a;
}

.hero-cta-secondary:hover,
.hero-cta-secondary:focus-visible {
    background: rgba(139, 92, 246, .18);
    border-color: var(--cyber-purple);
    color: #fff;
}

.hero-cta:active {
    transform: translateY(0) scale(.985);
}

/* ── Mobile (SKILL.md 4.7: collapse declared explicitly, desktop rules untouched) ── */
@media (max-width: 768px) {

    .hero-cyber {
        padding-block: 1rem 0;
    }

    /* rusty begin update | 2026-09-03 03:40 */
    /* Action: MOBILE RESCUE. The stack was centred on a short slide, so the glass box
       and its text sat straight across the middle of the artwork and buried it.
       Three changes together fix it:
         1. a much taller slide (80svh - the SMALL viewport unit, so the browser chrome
            being visible cannot push the hero taller than the screen),
         2. the stack pushed to the BOTTOM of the shared grid cell, leaving the top of
            the frame (where the character art sits) completely clear,
         3. tighter padding so the box itself takes less of what is left.
       align-self: end is the grid equivalent of the "margin-top: auto" flex trick -
       these are overlapping grid items (grid-area: 1/1), not flex children. */
    /* rusty begin update | 2026-09-16 15:05 */
    /* Action: the phone frame now follows the uploaded image's own aspect ratio instead of
       being pinned to 80svh (superseding the MOBILE RESCUE height above, whose stack
       positioning is kept). A 16:9 upload cannot fill a portrait 80svh frame without
       either cropping the sides - the original complaint - or turning ~68% of the frame
       into blurred filler. So the frame shrinks to the picture rather than forcing the
       picture into the frame: no crop, no distortion, and no bands at all on phones.
       Swiper gets autoHeight:true in plugin.js so the track follows the active slide when
       two slides have different aspect ratios. */
    .hero-cyber-swiper {
        min-height: 0;
    }

    .hero-slide-media {
        height: auto;
        min-height: 0;
    }

    .hero-slide-img {
        height: auto;
    }

    /* Nothing left to letterbox once the frame matches the image, so the blurred backdrop
       is dropped entirely on phones - also removes its per-slide raster layer. */
    .hero-slide-img-fill {
        display: none;
    }
    /* rusty end update */

    .hero-cyber-stack {
        justify-self: stretch;
        align-self: end;
        width: auto;
        max-width: none;
        padding: .75rem .9rem;
        margin-block-end: 2rem;
        background: linear-gradient(to top, rgba(5, 5, 8, .62) 0%, rgba(5, 5, 8, .3) 55%, rgba(5, 5, 8, 0) 100%);
    }

    /* The caption used to sit 2.75rem off the bottom, which is exactly where the stack
       now lives. Moved to the top of the frame so the two cannot collide. */
    .hero-slide-caption {
        inset-inline: 1rem;
        inset-block-start: 1rem;
        inset-block-end: auto;
        max-width: none;
        font-size: .9rem;
    }
    /* rusty end update */

    .hero-cta-row {
        margin-block-start: 1.25rem;
    }

    .hero-cta {
        flex: 1 1 auto;
        padding: .8rem 1.1rem;
        font-size: .95rem;
    }
}

@media (prefers-reduced-motion: reduce) {

    .hero-title-accent {
        animation: none !important;
    }
}

/* rusty end new code */


/* rusty begin new code | 2026-09-02 17:20 */
/* Action: HUD ticker. Fresh build, not a restore of the legacy .cyber-ticker-* rules.
   Motion justification (SKILL.md 5, "motion must be motivated"): the strip carries a live
   feed of the newest activity across the platform, and the horizontal drift is what
   communicates that it is live rather than a static list.
   This is the ONLY marquee on the page (SKILL.md 5, MARQUEE-MAX-ONE-PER-PAGE). */

.hud-ticker {
    display: flex;
    align-items: stretch;
    gap: 0;
    width: min(1280px, calc(100% - 2rem));
    /* rusty begin update | 2026-09-03 03:40 */
    /* Action: sits flush under the slider. --home-gap (1.25rem) still read as a visible
       break; 4px reads as one unit with the hero. The hero's own bottom padding is
       zeroed alongside this, otherwise it would reintroduce the gap. */
    margin: 4px auto 0;
    /* rusty end update */
    /* rusty begin update | 2026-09-03 04:10 */
    /* Action: lifted the ticker off the page ground so it reads as its own HUD element.
       Flatter, darker fill instead of the purple gradient, a cyan edge, and an inset
       cyan glow that traces the border from the inside (SKILL.md 9.A: inner light, not
       an outer neon halo).
       border-radius deliberately stays var(--home-radius) rather than dropping to 8px:
       it already has a radius, and 14px is the SHAPE CONSISTENCY LOCK value shared with
       the feature cards and the hero CTAs. */
    border: 1px solid rgba(6, 182, 212, .25);
    border-radius: var(--home-radius);
    background: rgba(10, 10, 15, .9);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 4px 24px rgba(0, 0, 0, .5), inset 0 0 12px rgba(6, 182, 212, .1);
    /* rusty end update */
    overflow: hidden;
}

/* ── Leading HUD chip ──────────────────────────────────────────────────────── */
.hud-ticker-label {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex: 0 0 auto;
    padding: .85rem 1.1rem;
    background: linear-gradient(180deg, rgba(6, 182, 212, .16), rgba(6, 182, 212, .07));
    border-inline-end: var(--home-border);
    color: var(--cyber-cyan);
    font-weight: 800;
    font-size: .82rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    white-space: nowrap;
}

.hud-ticker-label-icon {
    width: 1.05rem;
    height: 1.05rem;
    flex: 0 0 auto;
}

/* ── Viewport ──────────────────────────────────────────────────────────────── */
.hud-ticker-viewport {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    /* Soft edge fade so items dissolve out rather than clipping on a hard line. */
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 2.5rem, #000 calc(100% - 2.5rem), transparent 100%);
    mask-image: linear-gradient(to right, transparent 0, #000 2.5rem, #000 calc(100% - 2.5rem), transparent 100%);
}

.hud-ticker-track {
    display: flex;
    width: max-content;
    /* Two identical groups; translating exactly one group width loops seamlessly. */
    animation: hud-ticker-drift var(--hud-ticker-duration, 40s) linear infinite;
    will-change: transform;
}

/* RTL reads right to left, so the track must travel the opposite way. */
html[dir="rtl"] .hud-ticker-track {
    animation-name: hud-ticker-drift-rtl;
}

@keyframes hud-ticker-drift {
    from {
        transform: translate3d(0, 0, 0);
    }

    to {
        transform: translate3d(-50%, 0, 0);
    }
}

@keyframes hud-ticker-drift-rtl {
    from {
        transform: translate3d(0, 0, 0);
    }

    to {
        transform: translate3d(50%, 0, 0);
    }
}

/* Pause on hover AND on keyboard focus, so a keyboard user can reach a link. */
.hud-ticker:hover .hud-ticker-track,
.hud-ticker:focus-within .hud-ticker-track {
    animation-play-state: paused;
}

/* ── Items ─────────────────────────────────────────────────────────────────── */
.hud-ticker-group {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    gap: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

.hud-ticker-item {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    flex: 0 0 auto;
    padding: .85rem 1.5rem;
    white-space: nowrap;
}

/* Hairline separator between entries instead of a repeated logo image. */
.hud-ticker-item+.hud-ticker-item {
    border-inline-start: 1px solid rgba(139, 92, 246, .16);
}

.hud-ticker-section {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    color: var(--cyber-purple);
    font-size: .78rem;
    font-weight: 800;
    letter-spacing: .04em;
    text-decoration: none;
    text-transform: uppercase;
    transition: color .25s var(--home-ease);
}

.hud-ticker-item-icon {
    width: .95rem;
    height: .95rem;
    flex: 0 0 auto;
}

.hud-ticker-title {
    color: #e8eef7;
    font-size: 1rem;
    font-weight: 700;
    text-decoration: none;
    transition: color .25s var(--home-ease);
}

.hud-ticker-section:hover,
.hud-ticker-section:focus-visible {
    color: var(--cyber-cyan);
}

.hud-ticker-title:hover,
.hud-ticker-title:focus-visible {
    color: var(--cyber-cyan);
}

/* ── Mobile ────────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {

    .hud-ticker {
        width: calc(100% - 1.5rem);
        border-radius: var(--home-radius);
    }

    .hud-ticker-label-text {
        display: none;
        /* icon-only chip to buy back horizontal space */
    }

    .hud-ticker-label {
        padding: .75rem .8rem;
    }

    .hud-ticker-item {
        padding: .75rem 1rem;
        gap: .45rem;
    }

    .hud-ticker-title {
        font-size: .9rem;
    }

    .hud-ticker-section {
        font-size: .7rem;
    }
}

/* ── Reduced motion: no drift. Becomes a static, manually scrollable list. ──── */
@media (prefers-reduced-motion: reduce) {

    .hud-ticker-track {
        animation: none !important;
        transform: none !important;
        width: auto;
        will-change: auto;
    }

    /* The duplicate group only exists to make the loop seamless; with no loop it is
       redundant repetition, so drop it entirely. */
    .hud-ticker-group[aria-hidden="true"] {
        display: none;
    }

    .hud-ticker-viewport {
        overflow-x: auto;
        scrollbar-width: thin;
        -webkit-mask-image: none;
        mask-image: none;
    }
}

/* rusty end new code */


/* rusty begin update | 2026-09-02 20:05 */
/* Action: One unified 1+4 grid engine for Games, Training and Forums.

   Earlier the featured cell spanned 2 of 4 columns (50% width), which read as
   overwhelming, and Training/Forums pinned it to the inline-END (physical left in RTL).
   Now: a 3-COLUMN track, featured = 1 column wide x 2 rows tall (33% width), pinned to
   column line 1 = inline-START = the physical RIGHT in this RTL site (physical left in
   LTR). The other four cells fill columns 2-3 as a 2x2. All three sections share this
   exact geometry; only the $modifier (cell styling) differs.

   Rows are capped (minmax 210-300px) so the 2-row featured cell stays
   poster-proportioned rather than growing into a tower when the small cells are tall. */

.home-feature {
    padding-block: var(--home-section-py);
    background: transparent;
}

.home-feature-grid {
    display: grid;
    /* SKILL.md 3.E: Grid, never flex percentage math */
    gap: var(--home-gap);
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(2, minmax(210px, 300px));
}

/* Featured: 1 col wide, both rows tall, pinned to the inline-start edge (physical right
   in RTL). Applies identically to Games, Training and Forums. */
.home-feature-grid> :first-child {
    grid-column: 1 / 2;
    grid-row: 1 / 3;
}

/* Every cell fills its track so the row cap actually constrains height. */
.home-feature-grid>* {
    min-width: 0;
    min-height: 0;
}

/* Games alone gets a wider gutter so the 3D boxes have breathing room. */
.home-feature--games .home-feature-grid {
    gap: clamp(1.5rem, 2.4vw, 2.25rem);
}

/* ── Adapting to the real item count ───────────────────────────────────────── */
/* SKILL.md 4.7 BENTO CELL COUNT RULE: N items -> N cells, never a hole. Training only
   returns 4 rows, so featured + 3 small leaves one empty slot in the 2x2; the last
   small cell then spans both of columns 2-3 to close row 2. */
.home-feature-grid--4> :last-child {
    grid-column: span 2;
}

/* At 3 items or fewer an asymmetric featured span cannot tile cleanly, so the grid
   degrades to equal columns with no featured span at all.
   !important is deliberate: it has to beat `.home-feature-grid > :first-child` and the
   base track definition without restating the count modifier on every selector. */
.home-feature-grid--1,
.home-feature-grid--2,
.home-feature-grid--3 {
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)) !important;
    grid-template-rows: none !important;
    grid-auto-rows: minmax(220px, auto) !important;
}

.home-feature-grid--1>*,
.home-feature-grid--2>*,
.home-feature-grid--3>* {
    grid-column: auto !important;
    grid-row: auto !important;
}

/* ── Shared cell ───────────────────────────────────────────────────────────── */
.home-feature-cell {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow: hidden;
    border: var(--home-border);
    border-radius: var(--home-radius);
    background: var(--cyber-card);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    color: var(--cyber-text);
    text-decoration: none;
    transition: transform .35s var(--home-ease), border-color .35s var(--home-ease),
        box-shadow .35s var(--home-ease);
}

.home-feature-cell:hover,
.home-feature-cell:focus-visible {
    transform: translateY(-4px);
    border-color: rgba(6, 182, 212, .45);
    /* Tinted to the page ground, not a black drop shadow (SKILL.md 4.4). */
    box-shadow: 0 16px 36px rgba(5, 5, 8, .5);
    color: var(--cyber-text);
}

.home-feature-cell-thumb {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    background: rgba(5, 5, 8, .45);
}

.home-feature-cell-thumb img {
    width: 100%;
    height: 100%;
    min-height: 130px;
    object-fit: cover;
    display: block;
    transition: transform .5s var(--home-ease);
}

.home-feature-cell:hover .home-feature-cell-thumb img {
    transform: scale(1.04);
}

.home-feature-cell-body {
    flex: 0 0 auto;
    padding: .85rem 1rem 1rem;
}

.home-feature-cell-title {
    margin: 0;
    color: #fff;
    font-size: 1rem;
    font-weight: 800;
    line-height: 1.4;
    /* Two-line clamp keeps every small cell the same height regardless of title length. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.home-feature-cell-exp {
    margin: .5rem 0 0;
    color: #b9c4d4;
    font-size: .9rem;
    line-height: 1.65;
}

.home-feature-cell-price {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    margin-block-start: .55rem;
    padding: .2rem .6rem;
    border-radius: 999px;
    background: rgba(6, 182, 212, .12);
    color: var(--cyber-cyan);
    font-size: .82rem;
    font-weight: 800;
}

.home-feature-cell-price .price-symbol {
    height: .85em;
    width: auto;
}

/* ── Forum-cell extras ─────────────────────────────────────────────────────── */
.home-feature-cell-author {
    display: flex;
    align-items: center;
    gap: .35rem;
    margin-block-end: .5rem;
}

.home-feature-cell-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    object-fit: cover;
}

.home-feature-cell-verified {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    background-color: var(--cyber-cyan);
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
}

.home-feature-cell-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    margin-block-start: .4rem;
    color: #8f9cb0;
    font-size: .78rem;
}

/* Middot separator generated in CSS. SKILL.md 9.G bans the en-dash the old markup used
   here; the middot is permitted and is capped at one per line. */
.home-feature-cell-meta>*+*::before {
    content: "·";
    margin-inline: .4rem;
    opacity: .55;
}

/* ── Featured cell ─────────────────────────────────────────────────────────── */
.home-feature-cell.is-featured .home-feature-cell-title {
    font-size: 1.45rem;
    -webkit-line-clamp: 3;
}

.home-feature-cell.is-featured .home-feature-cell-body {
    padding: 1.1rem 1.35rem 1.35rem;
}

.home-feature-cell.is-featured .home-feature-cell-avatar {
    width: 34px;
    height: 34px;
}

/* ── 3D game card as a grid child ──────────────────────────────────────────── */
/* game-3d-card.blade.php normally emits a Bootstrap column; on the homepage it is handed
   wrapperClass="home-feature-cell-wrap" so it becomes a plain grid cell instead. */
.home-feature-cell-wrap {
    display: flex;
    min-width: 0;
}

.home-feature-cell-wrap>.game-3d-case-container {
    width: 100%;
}

/* ── Section header: title + "More", opposite ends ─────────────────────────── */
/* Flex + space-between: the h3 sits at inline-start (right in RTL, left in LTR) and
   the button at inline-end. This is the same pattern the departments header already
   uses, so the page reads consistently. */
.home-feature-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* rusty begin update | 2026-09-02 21:30 */
    /* Action: wrap allowed so a long title + the "More" button never overrun a narrow
       viewport - on wrap the button drops below the title at the inline-start edge
       rather than pushing past the screen. gap is the row-gap too (shorthand). */
    flex-wrap: wrap;
    /* rusty end update */
    gap: 1rem;
    margin-block-end: 2rem;
}

.home-feature-head .sec-tit {
    margin: 0 !important;
    text-align: start;
}

.home-more-btn {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    flex-shrink: 0;
    background: var(--cyber-cyan) !important;
    border: none !important;
    border-radius: var(--home-radius) !important;
    padding: .6rem 1.35rem;
    color: #04141a !important;
    font-weight: 800;
    white-space: nowrap;
    transition: transform .25s var(--home-ease), background .25s var(--home-ease);
}

.home-more-btn:hover,
.home-more-btn:focus-visible {
    background: #22d3ee !important;
    transform: translateY(-2px);
    color: #04141a !important;
}

.home-more-btn-icon {
    width: .95rem;
    height: .95rem;
}

/* The arrow glyph points inline-forward: left for RTL reading, right for LTR. */
html[dir="ltr"] .home-more-btn-icon {
    transform: scaleX(-1);
}

/* rusty begin new code | 2026-09-16 12:25 */
/* Action: Segmented view switch for the departments header, replacing the stock
   Bootstrap .btn-outline-light toggle (which carried no custom styling at all and
   read as unthemed chrome against the neon/glass surfaces around it). Two icon-only
   buttons instead of one label-swapping button, so the active view is stated rather
   than inferred. Sizing is scoped as .dept-view-btn .dept-view-ico (two classes) so
   it reliably beats the single-class .macblash-cyber-icon 1.5em default regardless
   of stylesheet load order. */
.dept-view-switch {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    flex-shrink: 0;
    padding: .25rem;
    border-radius: var(--home-radius);
    background: rgba(255, 255, 255, .05);
    border: 1px solid rgba(255, 255, 255, .12);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}

.dept-view-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: none;
    border-radius: calc(var(--home-radius) - 5px);
    background: transparent;
    color: rgba(255, 255, 255, .62);
    cursor: pointer;
    transition: background .25s var(--home-ease), color .25s var(--home-ease);
}

.dept-view-btn:hover,
.dept-view-btn:focus-visible {
    color: #fff;
    background: rgba(255, 255, 255, .1);
}

.dept-view-btn.is-active {
    background: var(--cyber-cyan);
    color: #04141a;
}

.dept-view-btn .dept-view-ico {
    width: 1.15rem;
    height: 1.15rem;
}

.dept-view-ico--carousel {
    -webkit-mask-image: url('https://api.iconify.design/ph/cards-three-bold.svg');
    mask-image: url('https://api.iconify.design/ph/cards-three-bold.svg');
}

.dept-view-ico--grid {
    -webkit-mask-image: url('https://api.iconify.design/ph/squares-four-bold.svg');
    mask-image: url('https://api.iconify.design/ph/squares-four-bold.svg');
}
/* rusty end new code */

@media (max-width: 768px) {
    .home-feature-head {
        margin-block-end: 1.25rem;
        gap: .6rem;
    }

    /* .sec-tit is 48px globally; that plus a button in one flex row overflows a phone. */
    .home-feature-head .sec-tit {
        font-size: 1.6rem;
        line-height: 1.2;
    }

    .home-more-btn {
        padding: .5rem .9rem;
        font-size: .8rem;
    }

    .home-more-btn-icon {
        width: .8rem;
        height: .8rem;
    }

    /* rusty begin new code | 2026-09-16 12:25 */
    /* Action: Tighten the view switch on phones so title + control keep one row. */
    .dept-view-btn {
        width: 2rem;
        height: 2rem;
    }

    .dept-view-btn .dept-view-ico {
        width: 1rem;
        height: 1rem;
    }
    /* rusty end new code */
}

/* ── Tablet: 3 cols -> 2 cols. Featured becomes a full-width banner on top, the
      other four sit 2x2 beneath it. ─────────────────────────────────────────── */
@media (max-width: 992px) {

    .home-feature-grid {
        grid-template-columns: repeat(2, 1fr);
        grid-template-rows: none;
        grid-auto-rows: minmax(200px, 300px);
    }

    .home-feature-grid> :first-child {
        grid-column: 1 / -1;
        grid-row: auto;
    }

    /* the span-2 close for a 4-item grid is a no-op once columns are equal */
    .home-feature-grid--4> :last-child {
        grid-column: auto;
    }
}

/* ── Mobile: strict single column, declared explicitly (SKILL.md 4.7 / 7) ───── */
@media (max-width: 768px) {

    .home-feature-grid {
        grid-template-columns: 1fr;
        grid-template-rows: none;
        grid-auto-rows: auto;
    }

    .home-feature-grid> :first-child {
        grid-column: 1 / 2;
        grid-row: auto;
    }

    .home-feature-grid--4> :last-child {
        grid-column: auto;
    }

    .home-feature-cell-thumb img {
        min-height: 180px;
    }

    .home-feature-cell.is-featured .home-feature-cell-title {
        font-size: 1.2rem;
    }
}

/* rusty end update */


/* rusty begin new code | 2026-09-02 18:05 */
/* Action: Departments carousel restyle. Folds the "جميع الاقسام" rail into the same
   dark-glass language as the hero, ticker and feature grids.

   What changes: the white polaroid surface becomes glass on --home-border /
   --home-radius, the title lightens to suit it, and the four arcade "power-on" and
   "throw" animations are neutralised so cards simply glide on the transition that
   .polaroid-card already declares. That glide IS the calm entrance: the choppy part was
   the keyframe layer fighting the transition layer, not the movement itself.

   What deliberately does NOT change: position, transform, transform-origin, z-index or
   any [data-state] rule. Those drive the carousel state machine in plugin.js, and the
   mobile perspective/isolation fixes in macblash-site-theme.css guard against the GPU
   layer leaks called out in CLAUDE.md. Visual treatment only. */

/* ── Card surface ──────────────────────────────────────────────────────────── */
.dept-swiper-section .polaroid-card {
    background-color: var(--cyber-card) !important;
    background-image: linear-gradient(180deg, rgba(139, 92, 246, .07), rgba(10, 10, 20, .55)) !important;
    border: var(--home-border) !important;
    border-radius: var(--home-radius) !important;
    backdrop-filter: blur(10px) !important;
    -webkit-backdrop-filter: blur(10px) !important;
    /* Tinted to the page ground rather than a pure-black drop shadow (SKILL.md 4.4). */
    box-shadow: 0 14px 34px rgba(5, 5, 8, .5) !important;
}

.dept-swiper-section .polaroid-card .img-container {
    border-radius: calc(var(--home-radius) - 4px) !important;
    overflow: hidden !important;
}

.dept-swiper-section .polaroid-card .text-container {
    border-top: 1px solid rgba(139, 92, 246, .14) !important;
}

/* Title now sits on glass, not on white card stock. */
.dept-swiper-section .polaroid-card h3,
.dept-swiper-section .polaroid-card .card-title {
    color: #cbd5e1 !important;
    text-shadow: none !important;
}

.dept-swiper-section .carousel-mode .polaroid-card[data-state="active"] h3,
.dept-swiper-section .carousel-mode .polaroid-card[data-state="active"] .card-title,
#cardContainerRoot.grid-mode .polaroid-card h3,
#cardContainerRoot.grid-mode .polaroid-card .card-title {
    color: #fff !important;
    /* No outer neon glow (SKILL.md 9.A); prominence comes from weight and contrast. */
    text-shadow: none !important;
}

.dept-swiper-section .carousel-mode .polaroid-card[data-state="active"] {
    border-color: rgba(6, 182, 212, .45) !important;
}

/* ── Retire the arcade motion layer ────────────────────────────────────────── */
/* cartridge-power-on (flicker), polaroid-throw-from-left/right (the choppy throws),
   img-border-power-on and title-power-on all ran on top of the card's own transition.
   Killing the keyframes leaves the smooth cubic-bezier slide already declared on
   .polaroid-card, which is the calm entrance. */
.dept-swiper-section .carousel-mode .polaroid-card,
.dept-swiper-section .carousel-mode .polaroid-card[data-state="active"],
.dept-swiper-section .carousel-mode .polaroid-card.throw-from-right,
.dept-swiper-section .carousel-mode .polaroid-card.throw-from-left,
.dept-swiper-section .carousel-mode .polaroid-card[data-state="active"] .img-border-wrap,
.dept-swiper-section .carousel-mode .polaroid-card[data-state="active"] h3,
.dept-swiper-section .carousel-mode .polaroid-card[data-state="active"] .card-title {
    animation: none !important;
}

/* The throw classes also killed the transition and blocked pointer events mid-flight;
   restore both so a card stays clickable while it settles. */
.dept-swiper-section .carousel-mode .polaroid-card.throw-from-right,
.dept-swiper-section .carousel-mode .polaroid-card.throw-from-left {
    transition: transform .55s cubic-bezier(.16, 1, .3, 1),
        opacity .4s ease,
        box-shadow .4s ease,
        filter .4s ease !important;
    pointer-events: auto !important;
}

/* ── Minimal control rail (replaces .retro-dock-panel) ─────────────────────── */
.dept-rail {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .75rem;
    width: max-content;
    margin: 1.5rem auto 0;
    padding: .5rem .65rem;
    border: var(--home-border);
    border-radius: 999px;
    background: rgba(10, 10, 20, .6);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    transition: opacity .3s ease;
}

.dept-rail-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    padding: 0;
    border: 1px solid rgba(139, 92, 246, .28);
    border-radius: 50%;
    background: rgba(139, 92, 246, .08);
    color: var(--cyber-cyan);
    cursor: pointer;
    transition: background .25s var(--home-ease), border-color .25s var(--home-ease),
        transform .25s var(--home-ease), color .25s var(--home-ease);
}

.dept-rail-btn:hover,
.dept-rail-btn:focus-visible {
    background: rgba(6, 182, 212, .16);
    border-color: rgba(6, 182, 212, .5);
    color: #fff;
    transform: translateY(-2px);
}

.dept-rail-btn:active {
    transform: translateY(0) scale(.95);
}

.dept-rail-btn .macblash-cyber-icon {
    width: 1.1rem;
    height: 1.1rem;
}

/* Position announcements stay in the accessibility tree only. */
.dept-rail-status.visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

@media (max-width: 768px) {
    .dept-rail {
        gap: .5rem;
        margin-top: 1rem;
    }

    .dept-rail-btn {
        width: 38px;
        height: 38px;
    }
}

@media (prefers-reduced-motion: reduce) {

    .dept-swiper-section .polaroid-card,
    .dept-rail-btn {
        transition: none !important;
        animation: none !important;
    }
}

/* rusty end new code */


/* rusty begin new code | 2026-09-02 18:05 */
/* Action: PHASE 5 - seamless flow.

   The page was built as a stack of independent blocks: every legacy section in style.css
   declared its own `padding: 50px 0` (95px for departments), `background-attachment: fixed`
   and a full-bleed rgba(0,0,0,.9) ::before overlay, which macblash-site-theme.css then
   fought back with `background: transparent !important`. Two stylesheets arguing produced
   the blocky, disconnected feel.

   This block settles it in one place: one vertical rhythm token for every section, no
   per-section backgrounds, no parallax, and a single faint page-level gradient so the
   whole scroll reads as one deep environment (SKILL.md 4.11 keeps it inside one theme
   family - a tint, never an inversion).

   Everything here is scoped to .page-bg or to homepage-only sections, and this stylesheet
   is loaded only by index.blade.php, so no other page is touched. */

/* ── One rhythm for every section ──────────────────────────────────────────── */
/* rusty begin update | 2026-09-02 21:30 */
/* Action: added .games / .transactions to the transparent-section list so EVERY section
   defers its ground to the single .page-bg wash below - no section paints its own fill,
   which is what produced the alternating blue/grey bands in visual QA. */
.page-bg .dept-swiper-section,
.page-bg .departments,
.page-bg .games,
.page-bg .transactions,
.page-bg .home-feature,
.page-bg .discussion,
.page-bg .partners,
.page-bg .testimonials {
    padding-block: var(--home-section-py) !important;
    padding-inline: 0;
    background: transparent !important;
    background-image: none !important;
    background-attachment: initial !important;
    border: none !important;
    box-shadow: none !important;
}

/* rusty end update */

/* rusty begin new code | 2026-09-02 22:10 */
/* Action: Hero joins the flat page wash. .cyber-glass-pane is already transparent via the
   legacy "UNIFIED CLEAR BACKGROUND" block, but .digital-rain still paints a 30% cyan
   gradient over the first viewport - that was the blue/grey tint sitting on top of the
   WebGL canvas at the top of the page. Same two declarations as .games / .page-bg, kept
   as its own rule so the hero's min-height / flex-centring / padding system is untouched. */
.page-bg .hero-cyber,
.page-bg .hero-cyber-bg,
.page-bg .hero-cyber .digital-rain,
.page-bg .hero-cyber .cyber-glass-pane {
    background: transparent !important;
    background-image: none !important;
}

/* rusty end new code */

/* Belt and braces over the legacy dark overlays, several of which are only suppressed
   by a `display: none` further up the cascade. */
.page-bg .games::before,
.page-bg .departments::before,
.page-bg .discussion::before,
.page-bg .partners::before,
.page-bg .testimonials::before {
    content: none !important;
}

/* The departments section forced min-height:100dvh, so it ate a whole viewport on its
   own and was the single biggest contributor to the "blocky" scroll. Its carousel stage
   is sized by .view-container (height: 680px), not by the section, so releasing this
   costs nothing and lets the section sit in the shared rhythm. */
.page-bg .dept-swiper-section,
.page-bg .dept-swiper-section.departments {
    min-height: 0 !important;
}

/* .discussion only wraps the forums grid and the partners wall now, and both children
   carry their own rhythm, so the wrapper must not add a third layer of padding. */
.page-bg .discussion {
    padding-block: 0 !important;
}

/* ── One flat page wash ───────────────────────────────────────────────────── */
/* rusty begin update | 2026-09-02 21:30 */
/* Action: replaced the 180deg purple->cyan vertical gradient with a single uniform
   90%-opaque black. The gradient was reading as blue/grey banding behind the sections
   in visual QA; a flat wash dims the fixed WebGL canvas to one brightness for the whole
   scroll length instead. */
/* !important + the longhand background-color specifically: macblash-site-theme.css
   declares `background: transparent !important` on .page-bg, and that SHORTHAND would
   otherwise reset this. background-image is pinned to none for the same reason. */
.page-bg {
    position: relative;
    background-color: rgba(0, 0, 0, .9) !important;
    background-image: none !important;
}

/* rusty end update */

/* ── Footer joins the same rhythm ──────────────────────────────────────────── */
.footer-main {
    padding-block: var(--home-section-py) !important;
    background: transparent !important;
    background-attachment: initial !important;
}

/* The one hairline worth keeping: it separates the legal bar from the page body.
   Desaturated to match --home-border rather than the old full-strength accent. */
.footer-bar {
    border-top: 1px solid rgba(139, 92, 246, .16) !important;
}

/* ── Section headings ──────────────────────────────────────────────────────── */
/* With no borders or alternating backgrounds left, the heading and the scroll reveal are
   what mark a section boundary, so the heading needs real breathing room under it. */
/* rusty begin update | 2026-09-02 21:30 */
/* Action: added a 4px cyan bar on the inline-start edge (physical right in RTL, left in
   LTR) so every section title reads as a deliberate header now that section boxes and
   rules are gone. Legacy `text-center` is stripped from the markup so this bar and the
   left-aligned text stay consistent across all four homepage headings. */
.page-bg .sec-tit {
    margin-block-end: 2rem;
    border-inline-start: 4px solid var(--cyber-cyan);
    padding-inline-start: .85rem;
    line-height: 1.2;
}

/* rusty end update */

@media (max-width: 768px) {
    .page-bg .sec-tit {
        margin-block-end: 1.25rem;
    }

    /* rusty begin update | 2026-09-02 21:30 */
    /* Action: overflow safety net. `clip` (not `hidden`) so no scroll container is
       created and ScrollTrigger / any sticky child keep using the document scroller. */
    .page-bg {
        overflow-x: clip;
    }

    /* rusty end update */
}

/* ── Success Partners ─────────────────────────────────────────────────────────
   Pulled out of the old .discussion wrapper (whose collapse was hiding it) and
   restyled as glass tiles so the logo wall belongs to the same environment as the
   rest of the scroll. Logo-only, no captions (SKILL.md 4.8). */
.page-bg .partners .partner-item {
    height: 120px;
    padding: 1rem 1.25rem;
    border: var(--home-border);
    border-radius: var(--home-radius);
    background: rgba(15, 10, 42, .35);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    transition: transform .3s var(--home-ease), border-color .3s var(--home-ease),
        background .3s var(--home-ease);
}

.page-bg .partners .partner-item:hover {
    transform: translateY(-4px);
    border-color: rgba(6, 182, 212, .4);
    background: rgba(15, 10, 42, .55);
}

.page-bg .partners .partner-item img {
    max-height: 100%;
    max-width: 100%;
    object-fit: contain;
    opacity: .85;
    transition: opacity .3s var(--home-ease);
}

.page-bg .partners .partner-item:hover img {
    opacity: 1;
}

.page-bg .partners .col-lg-cu-20 {
    margin-bottom: var(--home-gap);
}

/* rusty end new code */