/* =========================================================================
   Rodrigo Lopes — portfolio
   styles.css

   1. VARIABLES  (colours, fonts, sizes, breakpoints — tweak here first)
   2. Base
   3. Header & footer (every page)
   4. Home
   5. Portfolio
   6. Project pages
   7. About
   ========================================================================= */


/* =========================================================================
   1. VARIABLES
   -------------------------------------------------------------------------
   BREAKPOINTS used in this file (CSS can't use variables inside @media,
   so if you change them, search for these numbers):
     phone   : below 768px
     tablet  : 768px – 1199px   ->  @media (min-width: 768px)
     desktop : 1200px and up    ->  @media (min-width: 1200px)
   ========================================================================= */
:root {
  /* Colours */
  --black: #000000;
  --white: #ffffff;
  --card-black: #050708;      /* black of the portfolio cards */
  --green: #3aa648;           /* hero circle (sampled from the mockup) */
  --yellow: #e8e825;          /* "WIP" text (sampled from the mockup) */

  /* Fonts */
  --font-serif: "Instrument Serif", "Times New Roman", serif;
  --font-sans: "DM Sans", Helvetica, Arial, sans-serif;

  /* Sizes */
  --pad: 21px;                /* left/right page margin */
  --fs-small: 12.5px;           /* labels, tags */
  --fs-header: 14px;            /* header links: a bit bigger on phones so they read the same as on desktop */
  --fs-logo: 20.5px;
  --fs-body: 16px;            /* paragraphs on project pages */
  --fs-about: 13px;           /* About page text */
  --fs-about-h: 13px;         /* About section headings */
  --fs-about-lead: 13px;    /* About intro */
  --fs-title: 64px;           /* big serif titles (project, about name) */
  --fs-spot-title: 20px;      /* title in the Home spotlights */
  --radius-card: 40px;        /* rounded corners of the project cards */
  --gap: 22px;                /* gap between cards */
  --content-max: 1600px;      /* pages with class "limit-width": widest the content gets; on bigger screens blank space appears on the sides */

}

@media (min-width: 768px) {
  :root {
    --fs-header: 12.5px;
    --fs-logo: 27px;   /* the Rodrigo Lopes logo: bigger on tablet and desktop (phone stays at the value at the top) */
    --fs-body: 18px;
    --fs-about: 21px;
    --fs-about-h: 21px;
    --fs-about-lead: 21px;
    --fs-spot-title: 42px;
  }
}

@media (min-width: 1200px) {
  :root {
    --fs-body: 16px;
    --fs-spot-title: 62px;
  }
}


/* =========================================================================
   2. BASE
   ========================================================================= */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--white);   /* needed so the header colour-inversion works */
  color: var(--black);
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: var(--fs-body);
  line-height: 1.35;
  -webkit-font-smoothing: antialiased;
}

img { display: block; max-width: 100%; height: auto; }

a { color: inherit; }

h1, h2, h3, p, ul, figure { margin: 0; padding: 0; }
ul { list-style: none; }

.serif { font-family: var(--font-serif); font-weight: 400; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

/* small label above a section ("Portfolio Spotlights", "More Work"...) */
.label {
  font-size: var(--fs-small);
  font-weight: 400;
  padding: 0 var(--pad);
}

/* full width thin line */
.divider { border: 0; border-top: 1px solid currentColor; margin: 0; }

/* small round dot + text ("● Editorial") */
.tags { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 10px var(--pad) 12px; }
.tags li {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--fs-small); font-weight: 300;
}
.tags li::before {
  content: ""; width: 14px; height: 14px; border-radius: 50%;
  background: currentColor; flex: none;
}


/* =========================================================================
   3. HEADER & FOOTER
   ========================================================================= */

/* The header is fixed, has no background, and its colour is the inverse of
   whatever is behind it (white + "difference" = black on white, white on
   black, and a contrasting colour over images). */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  display: flex; justify-content: space-between; align-items: center;
  padding: 18px var(--pad) 0;
  color: var(--white);
  mix-blend-mode: difference;
  font-size: var(--fs-header);
  font-weight: 700;   /* Bold */
  pointer-events: none;           /* let clicks pass through the empty gaps */
}
.site-header a,
.site-header .nav-pending { pointer-events: auto; text-decoration: none; }
.site-header a[aria-current="page"] { text-decoration: underline; text-underline-offset: 3px; }

/* "Ideas" and "Contacts": look like links, do nothing (see README) */
.site-header .nav-pending { cursor: default; }

.logo {
  font-family: var(--font-serif); font-weight: 400;
  font-size: var(--fs-logo); line-height: 0.88; text-align: center;
  text-decoration: none;
}
.logo span { display: block; }

/* pages that start with white space under the header (not full-bleed images) */
.under-header { padding-top: 78px; }

.site-footer {
  background: var(--black); color: var(--white);
  display: flex; justify-content: space-between; align-items: center;
  padding: 0 var(--pad); height: 96px;
}
.site-footer img { width: 28px; height: 28px; }
.site-footer .footer-name {
  font-family: var(--font-serif); font-weight: 400; font-size: 36px; line-height: 1;
}
@media (min-width: 1200px) {
  .site-footer { height: 100px; }
}


/* =========================================================================
   4. HOME
   ========================================================================= */

/* --- Hero: exactly one window tall --- */
.hero {
  position: relative;
  height: 100vh; height: 100svh; min-height: 520px;
  border-bottom: 1px solid var(--black);
  overflow: hidden;
}

/* The ball. Placeholder for the future animated ball: to replace it, swap
   what is inside .ball-wrap in index.html (the <img>) — nothing else. */
.ball-wrap {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
}
.ball {
  height: 77%; width: auto; max-width: none; flex: none;
}

.hero-bottom {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: end;
  padding: 0 var(--pad) 18px;
  font-size: var(--fs-small); font-weight: 500; line-height: 1.25;   /* Medium */
}
.hero-bottom .stars { align-self: center; font-size: 14px; font-weight: 700; line-height: 1; text-align: center; }
.hero-bottom .tagline { max-width: 11.5em; }
.hero-bottom .now { text-align: right; }
.hero-bottom .now span { display: block; }
.rotator { min-height: 1.25em; }
.rotator em { font-weight: 300; }
.rotator li[hidden] { display: none; }

/* --- Portfolio Spotlights --- */
.section-label { padding: 38px var(--pad) 26px; }

#spotlights {
  position: relative;
  --spot-h: calc(var(--fs-spot-title) * 1.15);
  --spot-gap: clamp(60px, 10vw, 140px);   /* EMPTY SPACE BETWEEN TWO PROJECTS — change this */
}

/* The text (tags, name, View Project): ONE element for the whole section. It is
   "sticky": it starts at the top of the first project, then holds at the
   vertical middle of the window. Scrolling only changes what it says (site.js),
   so it never moves, jumps or overlaps. The images are pulled up under it. */
.spot-text {
  position: sticky; top: calc(50vh - var(--spot-h) / 2); z-index: 2;
  height: var(--spot-h); margin-bottom: calc(var(--spot-h) * -1);
  display: flex; justify-content: space-between;   /* equal space between tags, title and View Project */
  gap: 12px;                                       /* never closer than this (long titles wrap onto 2 lines instead) */
  align-items: baseline;      /* first tag line, title and View Project share the title's baseline */
  padding: 0 var(--pad);
  color: var(--white);
  mix-blend-mode: difference;
  pointer-events: none;
}
.spot-text a { pointer-events: auto; }
.spot-tags { font-size: var(--fs-small); font-weight: 400; line-height: 1.2; }
.spot-title {
  font-family: var(--font-serif); font-weight: 400;
  font-size: var(--fs-spot-title); line-height: 1; text-align: center;
}
.spot-tags, .spot-link { flex: none; }
.spot-link {
  font-size: var(--fs-small); font-weight: 500;
  text-decoration: underline; text-underline-offset: 3px; white-space: nowrap;
}
.spot-img {
  display: block;
  padding: calc(var(--spot-gap) / 2) 0;   /* half the space between projects above and half below */
}
.spot-img img { width: 100%; height: auto; }


/* =========================================================================
   5. PORTFOLIO
   ========================================================================= */
.index-head {
  display: flex; justify-content: space-between;
  padding: 0 var(--pad); font-size: 14px; font-weight: 500;
  margin-bottom: 18px;
}

/* Filters: they read across and start a new line when a line is full. The
   columns and the equal space between them are worked out by site.js
   (see "Layout of the filters" there). */
.filters {
  /* simple fallback: filters flow across and wrap. site.js then switches
     this to a grid with equal gaps between columns. */
  display: flex; flex-wrap: wrap;
  gap: 10px 40px;
  padding: 0 var(--pad);
}
.filter { position: relative; display: block; }
.filter input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.filter label {
  display: flex; align-items: center; gap: 9px;
  font-size: 14px; font-weight: 300; cursor: pointer; white-space: nowrap;
}
.filter label::before {
  content: ""; width: 16px; height: 16px; border-radius: 50%; flex: none;
  border: 1px solid var(--black);
}
.filter input:checked + label { font-weight: 400; }
.filter input:checked + label::before { background: var(--black); }
.filter input:focus-visible + label { outline: 2px solid var(--black); outline-offset: 3px; }

.project-grid {
  display: grid; grid-template-columns: 1fr; gap: var(--gap);
  padding: 44px var(--pad) 70px;
  overflow-x: clip;   /* a peeled sticker may hang a little over the sides without adding a scrollbar */
}
@media (min-width: 768px)  { .project-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1200px) { .project-grid { grid-template-columns: repeat(3, 1fr); } }

.card {
  display: block; overflow: hidden; border-radius: var(--radius-card);
  background: var(--card-black);
}
.card img { width: 100%; height: auto; }
.card[hidden] { display: none; }

/* --- Sticker card (Portfolio): peels to show tags + name. See "STICKER CARD" in site.js --- */
.card.sticker {
  position: relative; overflow: visible; background: none;
  container-type: inline-size;
}
.sticker-front {
  position: relative; z-index: 1;   /* above the tags + name until it is peeled */
  display: block; width: 100%; padding: 0; border: 0; cursor: pointer;
  background: var(--card-black); border-radius: var(--radius-card); overflow: hidden;
}
/* The card image can't be picked up and dragged (which would cancel the peel
   when you click and move a little), and the card text can't be selected by accident. */
.card.sticker { -webkit-user-select: none; user-select: none; }
.sticker-front img { -webkit-user-drag: none; user-drag: none; pointer-events: none; }
.sticker-info { -webkit-user-select: text; user-select: text; }   /* ...except the name and tags, which can still be copied */

/* what you see under the peeled sticker: the dark card with white tags and name.
   (To use another colour, change --sticker-under.) */
.card.sticker { --sticker-under: var(--card-black); }
.card.sticker.sticker-light { --sticker-under: var(--white); }   /* More Work: white back... */
.sticker-light .sticker-under { color: var(--black); }            /* ...with black text */
.sticker-under {
  position: absolute; inset: 0;
  background: var(--sticker-under); border-radius: var(--radius-card);
  color: var(--white);
}
.sticker-info {
  position: absolute; left: 0; right: 0; bottom: 4cqw;
  padding: 0 4cqw;
}
.sticker-info .tags { padding: 0 0 1.5cqw; }
.sticker-title {
  display: inline-block;
  text-decoration: none;
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(22px, 7.4cqw, 40px); line-height: 1;
}

.card.sticker.is-peeled { z-index: 5; }   /* while peeled, the flap may hang over the neighbours */
/* the flap's shadow, only on the part of the sticker that is still stuck (never outside the card).
   Change the strength with the rgba() alpha, the softness with blur(). */
.sticker-shadow { position: absolute; inset: 0; display: none; pointer-events: none; }
.sticker-shadow-over { z-index: 1; }    /* the flap's shadow, over the part that is still stuck (none on the uncovered part with the name) */
.sticker-shadow-blur { position: absolute; filter: blur(9px); }
.sticker-shadow-shape { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.5); }
.sticker-flap { position: absolute; inset: 0; z-index: 2; display: none; cursor: pointer; }   /* (no outer shadow) */
.sticker-flap { pointer-events: none; }          /* only the visible (cut) flap takes clicks, so the name stays clickable */
/* THE BACK OF THE STICKER: metallic / holographic. Layers, bottom to top:
   silver base, the card's image (mirrored, silvered), rainbow sheen, light + shade (site.js). */
.sticker-flap-inner {
  position: absolute; pointer-events: auto; isolation: isolate;
  background: linear-gradient(135deg, #e9edf2 0%, #aeb4bc 38%, #f4f6f9 62%, #9aa1aa 100%);   /* silver */
}
.sticker-flap-tex {
  position: absolute; transform-origin: 0 0;           /* mirrored over the fold line by site.js */
  background: center / 100% 100% no-repeat;            /* (the image itself is set by site.js) */
  filter: grayscale(0.85) brightness(1.7) contrast(1.15);
  mix-blend-mode: multiply; opacity: 0.8;
}
/* The Portfolio cards are dark (black background), so their image would make the back of the
   sticker dark and over-saturate the rainbow. Inverting it first makes it look the same as on
   the white More Work cards: silver with a ghost of the artwork. */
.card.sticker:not(.sticker-light) .sticker-flap-tex { filter: invert(1) grayscale(1) brightness(1.45) contrast(1.05); }
.sticker-flap-holo {
  position: absolute; inset: 0; mix-blend-mode: color-dodge; opacity: 0.55;
  background-image: linear-gradient(115deg, #ff5fa8, #ffd45f, #6dffb0, #5fc4ff, #a96dff, #ff5fa8, #ffd45f, #6dffb0);
  background-size: 420px 420px;                        /* smaller = more, thinner rainbow bands */
}
.sticker-flap-shade { position: absolute; inset: 0; }   /* soft shading on top of the texture (site.js) */


/* =========================================================================
   6. PROJECT PAGES  (black background, white text)
   ========================================================================= */
body.theme-dark { background: var(--black); color: var(--white); }

.project-hero img { width: 100%; height: auto; }
#project-head.no-first-image { padding-top: 78px; }   /* no first image: leave room for the header */
.project-title {
  font-family: var(--font-serif); font-weight: 400;
  font-size: var(--fs-title); line-height: 1; letter-spacing: -0.01em;
  padding: 26px var(--pad) 26px;
}

/* ---- LIMIT WIDTH ON HUGE SCREENS ----
   Add class="limit-width" to a page's <body> and the content under the hero
   image (tags, title, texts, images, More Work) stops growing at --content-max
   (top of this file) and stays centred, leaving blank space on the sides of
   very wide screens. The header, the footer and the first (hero) image are NOT
   limited: they keep using the full width. Remove the class to go back to full
   width everywhere. */
body.limit-width { --pad: max(21px, calc((100vw - var(--content-max)) / 2 + 21px)); }
body.limit-width .site-header,
body.limit-width .site-footer { --pad: 21px; }   /* back to the normal edge margin */

/* ---- the three content modules: text, single-image, double-image ---- */
.modules { padding: 0 var(--pad); }
.module { margin-bottom: var(--gap); }   /* same space between modules as between the two images of a double module (--gap, top of this file) */
.module.text { margin-bottom: 48px; }
.module.text p { font-size: var(--fs-body); font-weight: 300; line-height: 1.5; }
.module.text p + p { margin-top: 1.3em; }
.module.single-image img { width: 100%; height: auto; }
.module.double-image { display: grid; grid-template-columns: 1fr; gap: var(--gap); }
.module.double-image img { width: 100%; height: auto; }
@media (min-width: 1200px) {   /* side by side on desktop only */
  .module.double-image { grid-template-columns: 1fr 1fr; }
}

/* ---- More Work ---- */
.more-work { margin-top: 60px; border-top: 1px solid var(--white); }
.more-work .label { padding-top: 26px; padding-bottom: 20px; }
.more-grid {
  display: grid; grid-template-columns: 1fr; gap: var(--gap);
  padding: 0 var(--pad) 60px;
  overflow-x: clip;   /* a peeled sticker may hang a little over the sides without adding a scrollbar */
}
.more-grid .card { background: var(--white); }
.more-grid .card.sticker { background: none; }
.more-grid .card:nth-child(n+3) { display: none; }          /* phone & tablet: 2 cards */
@media (min-width: 768px) { .more-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1200px) {
  .more-grid { grid-template-columns: repeat(3, 1fr); }
  .more-grid .card:nth-child(n+3) { display: block; }       /* desktop: 3 cards */
}


/* =========================================================================
   7. ABOUT
   ========================================================================= */
.about-portrait img { width: 100%; height: auto; }
.about-portrait { padding: 0 var(--pad); }
.about-name {
  font-family: var(--font-serif); font-weight: 400;
  font-size: var(--fs-title); line-height: 1; letter-spacing: -0.01em;
  padding: 26px var(--pad) 28px;
}
/* on phone the name breaks into three lines, as in the mockup */
@media (max-width: 767px) { .about-name { max-width: 300px; } }
.about-intro { padding: 0 var(--pad); font-size: var(--fs-about-lead); line-height: 1.5; }
.about-intro .lead { font-weight: 500; margin-bottom: 1.3em; }
.about-intro a { font-weight: 400; text-underline-offset: 3px; }

.cv { padding: 56px var(--pad) 90px; display: grid; grid-template-columns: 1fr; }
@media (min-width: 1200px) { .cv { grid-template-columns: 1fr 1fr; column-gap: 40px; } }
.cv h2 {
  font-family: var(--font-sans); font-weight: 400; font-size: var(--fs-about-h);
  text-decoration: underline; text-underline-offset: 4px; margin: 0 0 28px;
}
.cv-block { margin-bottom: 44px; }
.cv-entry { margin-bottom: 26px; font-size: var(--fs-about); line-height: 1.5; font-weight: 300; }
.cv-entry strong { font-weight: 400; }
.cv-entry em { font-style: italic; }
.cv-entry .cv-title { font-weight: 400; }

/* =========================================================================
   Reduced motion: nothing here animates, but if you add animations later,
   wrap them so they switch off for people who ask for that:
   @media (prefers-reduced-motion: no-preference) { ... }
   ========================================================================= */
