/* ===== Hand-drawn portfolio theme ===== */
:root {
    --ink: #2E2A27;          /* the marker color */
    --blue: #DBE9F2;         /* hero powder blue */
    --cream: #F3F0E1;        /* projects section */

    /* pulled straight out of WelcomePage.png */
    --charcoal: #383636;     /* the page, and the "Alex" plate itself */
    --gold: #CDAB54;         /* the plate's frame */
    --paper: #E0E1DD;        /* type on the dark page */
}

html {
    scroll-behavior: smooth;
}
body {
    margin: 0;
    background-color: #FFFFFF;
    color: var(--ink);
    font-family: 'Rubik', 'Trebuchet MS', sans-serif;   /* closest match to the welcome art's wordmark */
    padding-top: 76px; /* room for the fixed header */
    box-sizing: border-box;
}

h1, h2, h3 {
    font-family: 'Rubik', 'Trebuchet MS', sans-serif;
    font-weight: 900;
}

/* ===== Header ===== */
.header-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 28px;
    gap: 16px;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    flex-wrap: wrap;
    background-color: #FFFFFF;
}

.logo {
    display: flex;
    align-items: center;
    gap: 14px;
}

.bear {
    width: 46px;
    height: 46px;
    object-fit: contain;
    transform: rotate(-4deg);
}

#title {
    margin: 0;
    font-size: 30px;
    letter-spacing: 2px;
    color: #0A0A0A;
}

.header {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.header a {
    font-family: 'Rubik', 'Trebuchet MS', sans-serif;
    font-weight: 500;
    font-size: 22px;
    text-decoration: none;
    color: #0A0A0A;
    padding: 6px 12px;
    transition: transform 0.2s ease;
}

.header a:hover {
    transform: scale(1.08) rotate(-2deg);
}

/* ===== Projects section ===== */
.projects-section {
    background-color: var(--cream);
    padding: 60px 32px 40px;
}

.section-title {
    font-size: 40px;
    margin: 0 0 24px;
}

/* the line of instructions under a section heading */
.section-subtitle {
    font-size: 17px;
    font-weight: 400;
    margin: -18px 0 26px;
    opacity: 0.72;
}

.projects {
    display: flex;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
}

.project-card {
    flex: 1 1 280px;
    min-width: 220px;
    text-align: center;
}

.project-card img {
    width: 100%;
    height: auto;
    display: block;
    margin: 0 auto 12px;
    border-radius: 14px;
    transition: transform 0.3s ease;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}

.project-card img:hover {
    transform: scale(1.04) rotate(-1deg);
}

/* ===== Older-page helpers (About Me etc.) ===== */
.welcome-section,
.hobbies-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 24px 32px;
}

.welcome-section > div,
.hobbies-section > div {
    flex: 1 1 300px;
}

.welcome-section img,
.hobbies-section img {
    max-width: 90%;
    height: auto;
    display: block;
    border-radius: 14px;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}

.welcome-text,
#welcome-text {
    font-size: 20px;
    line-height: 1.6;
}

/* ===== One-page home =====
   Everything lives on the charcoal the welcome art's plate is drawn in, so the
   plate reads as a window cut into the page rather than a picture sitting on it. */
.home {
    background-color: var(--charcoal);
    color: var(--paper);
    padding-top: 0;   /* no fixed header on the one-pager */
}
.welcome-hero {
    position: relative;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}
.welcome-art-wrap {
    position: relative;
    width: min(92vw, 1100px);
    will-change: transform, opacity;   /* driven by the scroll handler */
}
.welcome-art {
    display: block;
    width: 100%;
    height: auto;
    user-select: none;
    -webkit-user-drag: none;
}

/* ===== Typing out "Alex" =====
   The name is pixel art inside the plate, so it cannot be typed as text. Instead a cover
   in the plate's exact colour (#383636) starts over all four letters and retracts one
   letter at a time, which reads as typing. Steps are the real letter gaps measured from
   the art: A ends x582, l x648, e x752, x x855 on its 1366x768 canvas. */
.alex-mask,
.alex-caret {
    position: absolute;
    top: 31.64%;
    height: 13.93%;
    pointer-events: none;
}
.alex-mask {
    right: 37.19%;         /* pinned just past the final letter */
    width: 25.84%;         /* covering all four to begin with */
    background-color: #383636;
    animation: alexType 1.2s steps(1, end) 0.3s both;
}
.alex-caret {
    left: 36.97%;
    width: 0.55%;
    background-color: #FFFFFF;
    /* Solid while the name types itself out, then blinks on for good. The blink's delay
       is the type delay plus its duration, so it takes over the moment typing lands. */
    animation: alexCaret 1.2s steps(1, end) 0.3s both,
               alexCaretBlink 1s steps(1, end) 1.5s infinite both;
}
@keyframes alexType {          /* the cover retracts past each letter in turn */
    0%   { width: 25.84%; }
    25%  { width: 18.81%; }
    50%  { width: 14.20%; }
    75%  { width: 6.66%; }
    100% { width: 0%; }
}
@keyframes alexCaret {         /* the caret rides the cover's leading edge */
    0%   { left: 36.97%; }
    25%  { left: 43.99%; }
    50%  { left: 48.61%; }
    75%  { left: 56.15%; }
    100% { left: 62.81%; }
}
@keyframes alexCaretBlink {
    0%, 49%   { opacity: 1; }
    50%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .alex-mask,
    .alex-caret { display: none; }   /* the name is simply there from the start */
}
.scroll-cue {
    position: absolute;
    bottom: 30px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    color: var(--gold);
    font-size: 17px;
    letter-spacing: 1px;
    pointer-events: none;
}
.scroll-cue svg {
    animation: cueBob 1.8s ease-in-out infinite;
}
@keyframes cueBob {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(5px); }
}
@media (prefers-reduced-motion: reduce) {
    .scroll-cue svg { animation: none; }
}

/* About me — same treatment as the welcome art: transparent PNG straight on the charcoal */
.about-section {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 24px 60px;   /* the lower star hangs past the art; this is its room */
}
.about-art-wrap {
    position: relative;
    width: min(92vw, 1100px);
}
.about-art {
    position: relative;
    z-index: 1;   /* the art paints over the stars, so the copy stays legible */
    width: 100%;
    height: auto;
    display: block;
    user-select: none;
    -webkit-user-drag: none;
}
/* Each star PNG is one small drawing on a big 1366x768 transparent canvas. Showing the
   whole canvas would push the page sideways, so each box is sized to the star's ink only
   and the background is zoomed to frame it. Boxes land where the art's own clipped copy
   sits, so the two line up and the star reads whole. */
.star {
    position: absolute;
    z-index: 0;   /* behind the art; only the clipped-off parts show past its edges */
    background-repeat: no-repeat;
    pointer-events: none;
}
.star-light {   /* was clipped by the art's left edge */
    left: -2.416%;
    top: 17.969%;
    width: 15.154%;
    height: 28.125%;
    background-image: url('LigthBlueStar.png');
    background-size: 659.9% 355.6%;
    background-position: 50.56% 52.17%;
}
.star-dark {    /* was clipped by the art's bottom edge */
    left: 78.184%;
    top: 81.120%;
    width: 15.959%;
    height: 28.255%;
    background-image: url('DarkBlueStar.png');
    background-size: 626.6% 353.9%;
    background-position: 50.44% 60.07%;
}

/* ===== Other works: the 3D model ===== */
.other-section {
    padding: 20px 32px 90px;
}
/* The section is the template artwork; the live model is dropped into the gold frame
   drawn on it. Percentages are that frame's interior (source px x361-1004, y160-612)
   as a share of the template's 1366x768 canvas. */
.mini-figure-wrap {
    position: relative;
    width: min(92vw, 1100px);
    margin: 0 auto;
}
.mini-figure-art {
    display: block;
    width: 100%;
    height: auto;
    user-select: none;
    -webkit-user-drag: none;
}
/* The template's own background is opaque, so unlike the about-me stars these sit over
   the art rather than behind it. Same drawings, aligned to the clipped copies by their
   uncut edges, so each star reads whole where the canvas cut it off. */
.mini-star-light {   /* clipped by the template's top edge */
    left: 75.381%;
    top: -1.336%;
    width: 14.699%;
    height: 27.281%;
    transform: rotate(5deg);
    background-image: url('LigthBlueStar.png');
    background-size: 659.9% 355.6%;
    background-position: 50.56% 52.17%;
}
.mini-star-dark {    /* clipped by the template's bottom edge */
    left: 73.382%;
    top: 84.102%;
    width: 15.959%;
    height: 28.255%;
    transform: rotate(-13deg);
    background-image: url('DarkBlueStar.png');
    background-size: 626.6% 353.9%;
    background-position: 50.44% 60.07%;
}

.mini-figure-model {
    position: absolute;
    left: 26.428%;
    top: 20.833%;
    width: 47.145%;
    height: 58.984%;
    background-color: #2E2E2E;   /* the panel colour behind the printed render */
    --poster-color: transparent;
    --progress-mask: transparent;
}
/* load progress, since the model is a big download */
.model-progress {
    position: absolute;
    left: 12%;
    right: 12%;
    bottom: 18px;
    height: 4px;
    border-radius: 4px;
    background-color: rgba(224, 225, 221, 0.18);
    overflow: hidden;
}
.model-progress span {
    display: block;
    width: 0%;
    height: 100%;
    background-color: var(--gold);
    transition: width 0.2s ease;
}
.model-progress.done {
    opacity: 0;
    transition: opacity 0.4s ease;
}

/* the carousel and footer sit on the same charcoal */
.home .projects-section {
    background-color: var(--charcoal);
}
.home .section-title {
    color: var(--paper);
}
.home .contact-section {
    margin-top: 0;
    background-color: var(--charcoal);
    color: var(--paper);
    border-top: 2px solid var(--gold);
}
.home .contact-section h3 {
    color: var(--gold);
    margin: 0 0 4px;
}
.home .contact-section p {
    margin: 0;
}

/* ===== Projects page ===== */
.projects-page {
    background-color: var(--blue);
}
.projects-page .projects-section {
    background-color: var(--blue);
}

/* ===== Project carousel ===== */
.carousel-wrapper {
    position: relative;   /* positioning context for the in-place book */
    /* the card image, transparent margins included — never taller than the
       room left under the header and title, or the book runs off the screen */
    --page-w: min(clamp(220px, 42vw, 34rem), calc((100vh - 300px) / 1.294));
    --art-w: calc(var(--page-w) * 0.8796);      /* just the cover art inside those margins */
    --page-h: calc(var(--art-w) / 0.71078);     /* exact cover-art aspect */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    min-height: calc(100vh - 280px);   /* fill what's left below the header and title */
}
.carousel-container {
    position: relative;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 60vh;
    cursor: grab;
    user-select: none;
    touch-action: pan-y;   /* let the page scroll vertically; we handle horizontal */
}
.carousel-container.grabbing {
    cursor: grabbing;
}
.carousel-container.grabbing .carousel-card {
    transition: none;   /* follow the cursor immediately while dragging */
}
.carousel-card {
    position: absolute;
    width: var(--page-w);
    height: auto;   /* fit the image's own proportions */
    pointer-events: none;   /* swipe happens on the container, no image ghost-drag */
    -webkit-user-drag: none;
    transition: transform 0.5s cubic-bezier(0.34, 1.3, 0.64, 1), opacity 0.3s ease;
}

/* ===== Openable book ===== */
.book-overlay {
    position: absolute;   /* sits inside the carousel, not the whole screen */
    inset: 0;
    z-index: 50;
    background: transparent;   /* keep the carousel visible around the book */
    display: flex;
    align-items: center;
    justify-content: center;
    perspective: 2600px;   /* gives the page turns real depth */
}
.book-overlay[hidden] {
    display: none;
}
.book-overlay:not([hidden]) {
    animation: bookOverlayIn 0.3s ease;
}
@keyframes bookOverlayIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}
/* no page-dragging or stray clicks once the book starts shutting */
.book-overlay.closing {
    pointer-events: none;
}
/* fades out after the pages have shut, while the card fades back in */
.book-overlay.fading:not([hidden]) {
    animation: bookOverlayOut 0.3s ease forwards;
}
@keyframes bookOverlayOut {
    from { opacity: 1; }
    to   { opacity: 0; }
}
.book {
    position: relative;
    width: calc(2 * var(--art-w));   /* two pages = twice the cover art */
    height: var(--page-h);           /* same height as the cover art */
    transform-style: preserve-3d;
    transition: transform 0.5s ease;   /* recentres as pages turn */
}
.leaf {
    position: absolute;
    top: 0;
    left: 50%;               /* right-hand page; spine at the book's centre */
    width: 50%;
    height: 100%;
    transform-origin: left center;
    transform-style: preserve-3d;
    transition: transform 0.6s ease;
    will-change: transform;
    cursor: grab;
}
.leaf .face {
    position: absolute;
    inset: 0;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    background-color: #E9EEF1;   /* blank pages match the scans' paper tone */
    background-repeat: no-repeat;
    /* page scans carry the same transparent margins as the covers
       (~4.5% left, 6.5% right, 2.3% top, 1.4% bottom) — zoom past them */
    background-size: 112.92% 103.9%;
    background-position: 41.3% 62%;
    border-radius: 3px 14px 14px 3px;   /* rounded outer corners */
    overflow: hidden;
}
.leaf .face.back {
    transform: rotateY(180deg);
    border-radius: 3px 14px 14px 3px;
}
/* A moving panel sitting over a printed still on a page. The rect is measured from the
   still it replaces, so it fills that box exactly. */
.page-media {
    position: absolute;
    display: block;
    object-fit: fill;
    pointer-events: none;   /* dragging here still turns the page */
}

/* ===== Index tab =====
   The tab is drawn into the page art just past the page's right edge (source px
   x 1441-1521, y 87-378), which the page crop above cuts off. This re-shows that
   strip as a button that sits on the outer edge of the page it belongs to.
   Sized against the book (two pages wide), so 5.83% of a page = 2.915% here. */
.page-tab {
    position: absolute;
    top: 2.1%;
    left: 100%;      /* the right page's outer edge, where its page is */
    width: 2.915%;
    height: 15.12%;
    padding: 0;
    border: 0;
    background-color: transparent;
    background-repeat: no-repeat;
    background-size: 1936% 687.3%;      /* zoom so only the tab strip lands in the box */
    background-position: 98.36% 5.09%;
    cursor: pointer;
    z-index: 200;
    transition: transform 0.2s ease, opacity 0.3s ease;
}
.page-tab:hover,
.page-tab:focus-visible {
    transform: translateX(4px);   /* nudges out when you point at it */
}
/* Once its page has turned it rides the left-hand stack, so the tab moves to that
   outer edge. Rotating rather than mirroring keeps the lettering the right way round. */
.page-tab.reverse {
    left: auto;
    right: 100%;
    transform: rotate(180deg);
}
.page-tab.reverse:hover,
.page-tab.reverse:focus-visible {
    transform: rotate(180deg) translateX(4px);
}

/* cover image fills the whole page: zoom past the PNG's transparent
   margins (~5% left, 7% right, 2.7% top, 1.7% bottom) so no white shows */
.leaf .face.cover {
    background-size: 113.69% 104.55%;
    background-position: 41.4% 60.9%;
}

/* ===== Dropdown (About Me) ===== */
.dropdown-container {
    max-width: 900px;
    margin: 24px auto;
    padding: 0 32px;
}
.dropdown-toggle {
    font-family: 'Rubik', 'Trebuchet MS', sans-serif;
    font-weight: 500;
    font-size: 20px;
    background-color: var(--ink);
    color: #FFFFFF;
    border: none;
    border-radius: 10px;
    padding: 10px 20px;
    cursor: pointer;
    transition: transform 0.2s ease;
}
.dropdown-toggle:hover {
    transform: scale(1.05) rotate(-1deg);
}
.dropdown-content {
    display: none;
    margin-top: 14px;
    padding: 18px 20px;
    background-color: var(--blue);
    border-radius: 14px;
}
.dropdown-content.open {
    display: block;
}
.dropdown-content ul {
    margin: 10px 0 0;
    padding-left: 20px;
}

/* ===== Footer ===== */
.contact-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
    margin-top: 40px;
    padding: 50px 32px;
    background-color: #FFFFFF;
    scroll-margin-top: 90px;
}

.socialicon {
    display: flex;
    gap: 20px;
}

/* ===== Responsive ===== */
@media (max-width: 900px) {
    .header-container {
        justify-content: center;
        text-align: center;
    }
    .header {
        justify-content: center;
    }
    .contact-section {
        flex-direction: column;
        text-align: center;
    }
}

@media (max-width: 600px) {
    body {
        padding-top: 120px;
    }
}
