/* ── Animated border highlight ──────────────────────────── */
/* @property lets the browser interpolate --border-angle      */
/* smoothly so conic-gradient animates without jumping.       */
@property --border-angle {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: true;
}

@property --border-angle-2 {
    syntax: '<angle>';
    initial-value: 90deg;
    inherits: true;
}


/* ── WebGL background canvas ─────────────────────────────── */
#bg-canvas {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: var(--z-background);
    display: block;
}

/* ── Grain overlay ───────────────────────────────────────── */
/* Sits at --z-grain (above blobs, below panels).             */
/* The panels' backdrop-filter:blur() smooths the grain away  */
/* inside them automatically — no extra logic needed.         */
.grain {
    position: fixed;
    inset: 0;
    z-index: var(--z-grain);
    pointer-events: none;
    opacity: var(--grain-opacity);
    filter: contrast(var(--grain-contrast));
    mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
    background-size: var(--grain-size) var(--grain-size);
    animation: grain var(--grain-speed) steps(1) infinite;
}

/* background-position shifts which part of the infinite tile is shown.
   No element edges involved — mathematically impossible to see a seam. */
@keyframes grain {
    0%   { background-position:   0px    0px; }
    10%  { background-position:  34px   71px; }
    20%  { background-position: -83px   22px; }
    30%  { background-position:  17px  -94px; }
    40%  { background-position: -49px   57px; }
    50%  { background-position:  95px  -31px; }
    60%  { background-position: -12px   88px; }
    70%  { background-position:  63px  -67px; }
    80%  { background-position: -77px   13px; }
    90%  { background-position:  28px   79px; }
}

/* ── Glass frame — blurs the background behind it ─────────── */
.page-frame {
    position: fixed;
    inset: var(--frame-padding-y) var(--frame-padding-x);
    background: linear-gradient(135deg, var(--color-panel-1), var(--color-panel-2));
    backdrop-filter: blur(var(--blur));
    -webkit-backdrop-filter: blur(var(--blur));
    box-shadow: var(--shadow);
    border-radius: var(--radius);
    border: var(--outline);
    z-index: var(--z-panel);
}

/* ── Frame shimmer — shared base ────────────────────────────────────────── */
/* Both ::before and ::after use padding:1px + mask-subtract to render      */
/* only on the 1px border strip. Only the background gradient differs.      */
.page-frame::before,
.page-frame::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    -webkit-mask:
        linear-gradient(#fff 0 0) content-box,
        linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
}

/* Shimmer B — wide soft arc */
.page-frame::before {
    background: conic-gradient(
        from var(--border-angle-2),
        rgba(255,255,255,0)    0deg,
        rgba(255,255,255,0)  240deg,
        rgba(255,255,255,0.35) 300deg,
        rgba(255,255,255,0.45) 330deg,
        rgba(255,255,255,0.35) 360deg
    );
}

/* Shimmer A — narrow bright arc */
.page-frame::after {
    background: conic-gradient(
        from var(--border-angle),
        rgba(255,255,255,0)           0deg,
        rgba(255,255,255,0)         310deg,
        var(--color-border-highlight) 350deg,
        rgba(255,255,255,0)         360deg
    );
}

/* ── Navbar — left strip, visually inside the frame ─────────── */
.navbar {
    position: fixed;
    top: var(--frame-padding-y);
    bottom: var(--frame-padding-y);
    left: var(--frame-padding-x);
    width: var(--nav-width);
    display: flex;
    align-items: center;
    z-index: var(--z-buttons);
}

.nav-icons {
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
    width: 100%;
    height: 100%;
}

.icon {
    width: 100%;
    height: var(--btn-h);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-icon);
    text-decoration: none;
    transform: translateX(var(--translate-x, 0px)) scale(var(--scale, 0.75));
    transition: transform 0.2s ease-out;
}

.icon img {
    width: var(--icon-size);
    height: var(--icon-size);
}

.logo {
    transform: scale(var(--scale, 2.5));
}

/* ── Sidebar — right strip, visually inside the frame ───────── */
.sidebar {
    position: fixed;
    top: var(--frame-padding-y);
    bottom: var(--frame-padding-y);
    right: var(--frame-padding-x);
    width: var(--sidebar-width);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    padding: var(--padding);
    z-index: var(--z-buttons);
    /* needed so .sidebar-hobbies (position:absolute) is contained here */
    isolation: isolate;
}

/* ── Sidebar logo — links to welcome section ────────────────── */
.sidebar-logo {
    display: block;
    width: 100%;
    aspect-ratio: 1;
    flex-shrink: 0;
    opacity: 0.85;
    transition: opacity 0.2s ease-out, visibility 0.4s;
}

.sidebar-logo:hover { opacity: 1; }

.sidebar-logo svg { width: 100%; height: 100%; }

.sidebar-logo .logo-body   { fill: var(--color-title); }
.sidebar-logo .logo-accent { fill: var(--color-accent); }

/* ── Filter toggle buttons — top of sidebar ─────────────────── */
.filter-buttons {
    display: flex;
    flex-direction: column;
    gap: calc(var(--gap) / 2);
    width: 100%;
}

/* Author display:flex overrides the UA [hidden]{display:none} — fix it explicitly */
.filter-buttons[hidden] { display: none; }

.filter-btn {
    width: 100%;
    padding: 5px 0;
    background: transparent;
    border: 1px solid var(--color-border);
    border-radius: calc(var(--radius) / 2);
    color: var(--color-title);
    font-family: var(--font);
    font-size: 11px;
    font-weight: 400;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    cursor: pointer;
    opacity: 0.35;
    transition: opacity 0.2s ease-out, background 0.2s ease-out, border-color 0.2s ease-out;
}

.filter-btn:hover {
    opacity: 0.7;
}

.filter-btn.active {
    opacity: 1;
    background: var(--color-border);
    border-color: var(--color-border-highlight);
}

/* ── Sidebar inner — socials block ──────────────────────────── */
.sidebar-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--gap);
    width: 100%;
    transition: opacity 0.4s ease-out;
}

/* ── Sidebar hobbies — about section only ────────────────────── */
.sidebar-hobbies {
    position:        absolute;
    inset:           0;
    display:         flex;
    flex-direction:  column;
    align-items:     center;
    justify-content: center;
    opacity:         0;
    pointer-events:  none;
    transition:      opacity 0.4s ease-out;
}

.sidebar-hobby {
    position:        relative;
    display:         flex;
    align-items:     center;
    justify-content: center;
    width:           100%;
    padding:         var(--padding) 0;
    opacity:         0.7;
    filter:          brightness(0) invert(1);
    transition:      opacity 0.2s ease-out;
}

.sidebar-hobby:hover { opacity: 1; }

.sidebar-hobby img {
    width:      var(--icon-size);
    height:     var(--icon-size);
    object-fit: contain;
    display:    block;
}

.sidebar-hobby::after {
    content:        attr(data-label);
    position:       absolute;
    top:            calc(50% + var(--icon-size) / 2 + 6px);
    left:           50%;
    transform:      translateX(-50%);
    white-space:    nowrap;
    font-size:      var(--text-caption);
    font-weight:    var(--text-caption-weight);
    letter-spacing: var(--text-caption-spacing);
    text-transform: uppercase;
    color:          var(--color-title);
    filter:         none;
    opacity:        0;
    transition:     opacity 0.2s ease-out;
    pointer-events: none;
}

.sidebar-hobby:hover::after { opacity: 1; }

/* ── Section-specific sidebar states ─────────────────────────── */
:root[data-section="section-about"] .sidebar-logo,
:root[data-section="section-about"] .sidebar-inner {
    opacity:        0;
    pointer-events: none;
}

:root[data-section="section-about"] .sidebar-hobbies {
    opacity:        1;
    pointer-events: auto;
}

.sidebar-label {
    color: var(--color-title);
    font-size: 11px;
    font-weight: 400;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    text-shadow: var(--title-shadow);
    opacity: 0.5;
}

/* Icon size fills the sidebar minus padding on both sides and the column gap */
.social-icons {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--gap);
    width: 100%;
}

.social-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1;
    width: 100%;
    filter: brightness(0) invert(1);
    opacity: 0.7;
    transition: filter 0.2s ease-out, opacity 0.2s ease-out;
}

.social-icon:hover {
    filter: none;
    opacity: 1;
}

.social-icon img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* ── Content — blurs frame + background behind it ───────────── */
.content {
    position: fixed;
    top: 0;
    bottom: 0;
    left: calc(var(--frame-padding-x) + var(--nav-width));
    right: calc(var(--frame-padding-x) + var(--sidebar-width));
    overflow-y: auto;
    overflow-x: hidden;
    padding: var(--frame-padding-y) var(--padding) var(--padding-y);
    background: linear-gradient(160deg, var(--color-panel-2), var(--color-panel-1));
    backdrop-filter: blur(calc(var(--blur) / 2));
    -webkit-backdrop-filter: blur(calc(var(--blur) / 2));
    border: var(--outline);
    z-index: var(--z-foreground);

    scrollbar-width: none;
    -ms-overflow-style: none;

    mask-image: linear-gradient(
        to bottom,
        transparent 0px,
        black var(--scroll-fade),
        black calc(100% - var(--scroll-fade)),
        transparent 100%
    );
    -webkit-mask-image: linear-gradient(
        to bottom,
        transparent 0px,
        black var(--scroll-fade),
        black calc(100% - var(--scroll-fade)),
        transparent 100%
    );
}

/* ── Content border shimmers — shared base ───────────────────────────────── */
/* Fixed overlays outside the scroll container — always cover the full       */
/* viewport height. Left and right 1px strips only (no top/bottom border).  */
.content-border-shimmer,
.content-border-shimmer-2 {
    position: fixed;
    top: 0;
    bottom: 0;
    left: calc(var(--frame-padding-x) + var(--nav-width));
    right: calc(var(--frame-padding-x) + var(--sidebar-width));
    -webkit-mask:
        linear-gradient(to right, #fff 1px, transparent 1px),
        linear-gradient(to left,  #fff 1px, transparent 1px);
    -webkit-mask-composite: source-over;
    mask:
        linear-gradient(to right, #fff 1px, transparent 1px),
        linear-gradient(to left,  #fff 1px, transparent 1px);
    mask-composite: add;
    z-index: var(--z-foreground);
    pointer-events: none;
}

/* Shimmer A — narrow bright arc, +180deg so it opposes the frame highlight */
.content-border-shimmer {
    background: conic-gradient(
        from calc(var(--border-angle) + 180deg),
        rgba(255,255,255,0)           0deg,
        rgba(255,255,255,0)         310deg,
        var(--color-border-highlight) 350deg,
        rgba(255,255,255,0)         360deg
    );
}

/* Shimmer B — wide soft arc, +270deg offset */
.content-border-shimmer-2 {
    background: conic-gradient(
        from calc(var(--border-angle-2) + 270deg),
        rgba(255,255,255,0)    0deg,
        rgba(255,255,255,0)  240deg,
        rgba(255,255,255,0.35) 300deg,
        rgba(255,255,255,0.45) 330deg,
        rgba(255,255,255,0.35) 360deg
    );
}

.content::-webkit-scrollbar {
    display: none;
    width: 0;
    height: 0;
}

/* ── Gallery sections ────────────────────────────────────── */
.gallery-section {
    margin-bottom: var(--section-gap);
    scroll-margin-top: var(--scroll-offset);
}

/* ── Welcome section ─────────────────────────────────────── */
/* Height fills exactly from frame top to frame bottom.       */
/* Content padding-top = frame-padding-y, so section top      */
/* is visually flush with the frame top edge.                  */
#section-welcome {
    display: flex;
    flex-direction: column;
    /* pull the section up so its header occupies the above-frame space */
    margin-top: calc(-1 * var(--frame-padding-y));
    /* total = above-frame header + slideshow + one padding gap at bottom */
    height: calc(100dvh - var(--padding));
}

#section-welcome .section-header {
    flex-shrink: 0;
   
    height: calc(var(--frame-padding-y) - var(--padding));
    padding-top: 0;
    padding-bottom: 0;
}

/* ── Slideshow ───────────────────────────────────────────── */
.slideshow {
    margin-top: calc(2 * var(--padding));
    position: relative;
    flex: 1;
    min-height: 0;
    border-radius: var(--radius);
    overflow: hidden;
    border: var(--outline);
}

.slide {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    opacity: 0;
    transition: opacity 1s ease-in-out;
}

.slide.active {
    opacity: 1;
}

.gallery-section:last-child {
    margin-bottom: 0;
}

.section-header {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-end;
    gap: 6px;
    padding-top: var(--section-header-h);
    padding-bottom: var(--padding);
    will-change: transform;
}

.section-eyebrow {
    display: block;
    color: var(--color-title);
    font-size: var(--text-eyebrow);
    font-weight: 300;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    text-shadow: var(--title-shadow);
    opacity: 0;           /* JS drives opacity + transform — starts hidden */
    will-change: opacity, transform;
    border-top: 1px solid var(--color-border);
    padding-top: var(--gap);
    margin-left: calc(-1 * var(--padding));
    padding-left: var(--padding);
    width: calc(100% + 2 * var(--padding));
}

.section-title {
    margin: 0;
    color: var(--color-title);
    font-size: var(--text-title);
    font-weight: 200;
    line-height: 1;
    letter-spacing: var(--text-title-spacing);
    text-transform: uppercase;
    text-shadow: var(--title-shadow);
}

/* ── Masonry grid ────────────────────────────────────────── */
.masonry {
    columns: var(--masonry-columns);
    column-gap: var(--gap);
    margin-top: var(--padding);
    will-change: transform;
}

.tile {
    width: 100%;
    margin-bottom: var(--gap);
    break-inside: avoid;
    border-radius: var(--radius);
    border: var(--outline);
    overflow: hidden;
}

.tile a {
    display: block;
    width: 100%;
    height: 100%;
}

.tile img,
.tile video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ── Script download tiles ───────────────────────────── */
/* Text-only tiles for downloadable scripts with no thumbnail. */
/* Overrides .tile a height so the card sizes to its content. */
.tile-script a {
    height: auto;
    text-decoration: none;
}

.tile-script {
    transition: border-color 0.2s ease-out;
    cursor: pointer;
}

.tile-script:hover {
    border-color: var(--color-border-highlight);
}

.script-tile-inner {
    display:        flex;
    flex-direction: column;
    gap:            12px;
    padding:        var(--padding);
    min-height:     140px;
}

.script-tile-header {
    display:         flex;
    align-items:     flex-start;
    justify-content: space-between;
    gap:             8px;
}

.script-tile-title {
    font-size:      var(--text-label);
    font-weight:    var(--text-label-weight);
    letter-spacing: var(--text-label-spacing);
    text-transform: uppercase;
    color:          var(--color-title);
    opacity:        0.9;
    line-height:    1.3;
}

.script-tile-lang {
    font-size:      var(--text-caption);
    font-weight:    var(--text-caption-weight);
    letter-spacing: var(--text-caption-spacing);
    text-transform: uppercase;
    color:          var(--color-title);
    opacity:        0.45;
    white-space:    nowrap;
    flex-shrink:    0;
    border:         1px solid var(--color-border);
    border-radius:  calc(var(--radius) / 2);
    padding:        2px 7px;
}

.script-tile-desc {
    font-size:   var(--text-body);
    font-weight: var(--text-body-weight);
    line-height: var(--text-body-line-height);
    color:       var(--color-title);
    opacity:     0.55;
    margin:      0;
    flex:        1;
}

.script-tile-credits {
    font-size:   var(--text-caption);
    font-weight: var(--text-caption-weight);
    line-height: 1.6;
    color:       var(--color-title);
    opacity:     0.3;
    margin:      0;
}

.script-tile-footer {
    display:         flex;
    align-items:     center;
    justify-content: space-between;
    gap:             8px;
    padding-top:     10px;
    border-top:      1px solid var(--color-border);
    margin-top:      auto;
}

.script-tile-filename {
    font-size:   var(--text-caption);
    font-weight: var(--text-caption-weight);
    color:       var(--color-title);
    opacity:     0.28;
    font-family: monospace;
    letter-spacing: 0.03em;
}

.script-tile-btn {
    font-size:      var(--text-caption);
    font-weight:    var(--text-caption-weight);
    letter-spacing: var(--text-caption-spacing);
    text-transform: uppercase;
    color:          var(--color-title);
    opacity:        0.5;
    transition:     opacity 0.2s ease-out;
}

.tile-script:hover .script-tile-btn   { opacity: 1; }
.tile-script:hover .script-tile-title { opacity: 1; }

/* ── Combined scripts tile ───────────────────────────── */
.scripts-tile-inner {
    display:        flex;
    flex-direction: column;
    padding:        var(--padding);
    gap:            0;
}

/* Notice block */
.scripts-tile-notice {
    display:        flex;
    flex-direction: column;
    gap:            6px;
    padding-bottom: var(--padding);
    margin-bottom:  var(--padding);
    border-bottom:  1px solid var(--color-border);
}

.scripts-tile-notice-label {
    font-size:      var(--text-caption);
    font-weight:    var(--text-caption-weight);
    letter-spacing: var(--text-caption-spacing);
    text-transform: uppercase;
    color:          var(--color-title);
    opacity:        0.35;
}

.scripts-tile-notice-text {
    font-size:   var(--text-body);
    font-weight: var(--text-body-weight);
    line-height: var(--text-body-line-height);
    color:       var(--color-title);
    opacity:     0.4;
    margin:      0;
}

/* Script rows */
.scripts-tile-item {
    display:        flex;
    flex-direction: column;
    gap:            6px;
    padding:        var(--padding) 0;
    border-bottom:  1px solid rgba(255, 255, 255, 0.06);
}

.scripts-tile-item:last-child {
    border-bottom: none;
    padding-bottom: 0;
}

.scripts-tile-item-header {
    display:         flex;
    align-items:     center;
    justify-content: space-between;
    gap:             8px;
}

.scripts-tile-item-title {
    font-size:      var(--text-label);
    font-weight:    var(--text-label-weight);
    letter-spacing: var(--text-label-spacing);
    text-transform: uppercase;
    color:          var(--color-title);
    opacity:        0.9;
}

.scripts-tile-item-lang {
    font-size:      var(--text-caption);
    font-weight:    var(--text-caption-weight);
    letter-spacing: var(--text-caption-spacing);
    text-transform: uppercase;
    color:          var(--color-title);
    opacity:        0.4;
    white-space:    nowrap;
    flex-shrink:    0;
    border:         1px solid var(--color-border);
    border-radius:  calc(var(--radius) / 2);
    padding:        2px 7px;
}

.scripts-tile-item-desc {
    font-size:   var(--text-body);
    font-weight: var(--text-body-weight);
    line-height: var(--text-body-line-height);
    color:       var(--color-title);
    opacity:     0.5;
    margin:      0;
}

.scripts-tile-item-credits {
    font-size:      var(--text-caption);
    font-weight:    var(--text-caption-weight);
    letter-spacing: var(--text-caption-spacing);
    line-height:    1.6;
    color:          var(--color-title);
    opacity:        0.3;
    margin:         0;
    margin-top:     2px;
}

.scripts-tile-item-btns {
    display:    flex;
    flex-wrap:  wrap;
    gap:        6px;
    margin-top: 8px;
}

.scripts-tile-item-btn {
    display:         flex;
    align-items:     center;
    justify-content: center;
    flex:            1 1 0;
    font-size:       var(--text-caption);
    font-weight:     var(--text-caption-weight);
    letter-spacing:  var(--text-caption-spacing);
    text-transform:  uppercase;
    text-decoration: none;
    text-align:      center;
    color:           var(--color-title);
    opacity:         0.5;
    border:          1px solid var(--color-border);
    border-radius:   calc(var(--radius) / 2);
    padding:         5px 10px;
    transition:      opacity 0.2s ease-out, border-color 0.2s ease-out;
}

.scripts-tile-item-btn:hover {
    opacity:      1;
    border-color: var(--color-border-highlight);
}
