/* ============================================================================
 * redesign.css — Francisca's visual design, layered over styles.css.
 *
 * HOW THE STYLESHEETS STACK (later files win):
 *   1. styles.css      base layout and structure          (Saber)
 *   2. animations.css  motion, homepage only              (Shristi)
 *   3. redesign.css    this file: the current look        (Saber + Francisca)
 *
 * Change the LOOK here. Leave styles.css for structure and animations.css for
 * Shristi's motion, so her pull request stays easy to compare and merge.
 *
 * WHERE THINGS ARE (in order):
 *   1. Fonts
 *   2. Design tokens
 *   3. Shared: body, header, footer, labels
 *   4. Homepage
 *   5. Event page            (register/)
 *   6. Inner pages           (events/, events/visible-java/, past-events/, mailing-list/, code-of-conduct/)
 *   7. Interactive overrides (Shristi's monogram)
 *   8. Figma lettering hooks
 *   9. Responsive
 *  10. Reduced motion
 *
 * NOTES
 *   - Rules are one per line to keep this file short and scannable.
 *   - Order matters within a section: later rules of equal weight win.
 *   - Heading sizes live here, NOT in the generated lettering spans, so
 *     headings stay responsive. See docs/TYPOGRAPHY.md.
 *   - Colours come from the tokens below wherever possible.
 *   - To update the design after Francisca sends a new Figma frame, see
 *     docs/UPDATING.md.
 * ========================================================================= */

/* --- 1. Fonts ------------------------------------------------------------ */
/* Self-hosted so the variable width/weight axes work offline. Licences sit next to the files. */
@font-face { font-family: Anybody; src: url('assets/fonts/Anybody[wdth,wght].ttf') format('truetype'); font-style: normal; font-weight: 100 900; font-stretch: 50% 150%; font-display: swap; }
@font-face { font-family: Anybody; src: url('assets/fonts/Anybody-Italic[wdth,wght].ttf') format('truetype'); font-style: italic; font-weight: 100 900; font-stretch: 50% 150%; font-display: swap; }
@font-face { font-family: 'Overpass Mono'; src: url('assets/fonts/OverpassMono[wght].ttf') format('truetype'); font-weight: 300 700; font-display: swap; }

/* --- 2. Design tokens ---------------------------------------------------- */
/* Overrides the defaults in styles.css. Change a colour here and it updates everywhere. */
:root {
 --paper: #edede9;      /* page background */
 --surface: #f4f4f1;    /* header, tinted sections */
 --tint: #e5e5e2;       /* subtle fills */
 --ink: #18181a;        /* text and dark bands */
 --muted: #62625e;      /* secondary text */
 --line: #c4c4c0;       /* borders */
 --soft-line: #dcdcd8;  /* lighter borders */
 --accent: #2d5bff;     /* blue: buttons, links, some headings */
 --orange: #ff4d2e;     /* upcoming band, event facts */
 --lime: #c8ff32;       /* mailing list, registration band */
 --cc-orange: var(--orange);  /* kept: older names used by styles.css */
 --accent-ink: var(--ink);
 --page-width: 1440px;  /* Figma frame width */
 --page-pad: clamp(1.25rem, 4.45vw, 4rem);
}

/* --- 3. Shared ----------------------------------------------------------- */
body { font-family: Anybody, Arial, sans-serif; font-weight: 300; font-kerning: normal; }
h1,h2,h3,p { overflow-wrap: break-word; }
button { font: inherit; }
/* Announcement bar above the header on every page (_data/site.yml → announcement). */
.announcement-bar { margin: 0; padding: .55rem var(--page-pad); color: var(--ink); background: var(--lime); border-bottom: 1px solid var(--ink); font-size: 13px; line-height: 1.4; text-align: center; }
.announcement-bar .eyebrow { display: inline; margin: 0 .5rem 0 0; color: var(--ink); }
.announcement-bar a { margin-left: .35rem; font-weight: 500; color: var(--ink); text-underline-offset: .2em; white-space: nowrap; }
.announcement-bar a:hover { color: var(--accent); }
.announcement-bar a:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }
.site-header { min-height: 56px; background: var(--surface); }
.site-header nav { font-size: 13px; color: var(--muted); flex-wrap: wrap; }
.site-header nav a { text-decoration: none; padding-block: .5rem; }
.site-header nav a:hover { color: var(--accent); text-decoration: underline; }
.site-header nav a[aria-current="page"] { color: var(--ink); text-decoration: underline; text-underline-offset: .35em; }
.logo { font-size: 13px; font-weight: 500; letter-spacing: .05em; font-variation-settings: 'wdth' 71; white-space: nowrap; }
/* Small mono labels: eyebrows, fact labels, section numbers, tags. */
.eyebrow,.event-facts span,.section-heading > p,.session-time,.tag-row span,.upcoming-facts span,.location-chip span { font-family: 'Overpass Mono', monospace; font-size: 10px; letter-spacing: .07em; }
.button { font-size: 14px; font-weight: 500; padding: .85rem 1.5rem; }
.button-light,.button-solid { color: white; background: var(--accent); border-color: var(--accent); }
.button:hover { filter: brightness(.9); }
.site-footer { font-size: 12px; border-top: 1px solid var(--line); gap: 1.5rem; }
.site-footer strong.logo { font-size: 12px; }
.design-credits { grid-column: 1 / -1; font-size: 11px; }  /* designer credits: keep on every page */
.organizer { display: flex; align-items: center; gap: .5rem; }
.icon-links { display: inline-flex; gap: .4rem; }
.icon-link { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; color: var(--ink); }
.icon-link:hover { color: var(--accent); }
.icon-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --- 4. Homepage --------------------------------------------------------- */
.home-hero { overflow: hidden; position: relative; padding-top: clamp(3rem,6.7vw,6rem); padding-bottom: clamp(3rem,6.7vw,6rem); }
/* Giant italic "CC FEST". Size is 400/1440 of the viewport, matching the Figma frame. */
.home-hero-title { position: relative; z-index: 1; font-family: Anybody, sans-serif; font-style: italic; font-weight: 400; font-variation-settings: 'wdth' 71; font-size: clamp(5rem,27.7778vw,25rem); letter-spacing: 0; line-height: .8; white-space: nowrap; margin: 0 0 2.5rem; }
.hero-rule { position: relative; z-index: 1; margin-bottom: 2.5rem; }
.home-hero-sub { font-size: clamp(.9rem,1.25vw,18px); line-height: 1.7; max-width: 480px; }
.hero-shape { --shape-w: clamp(65px,20vw,285px); position: absolute; bottom: calc(var(--shape-w) * -1.169); left: 0; width: var(--shape-w); height: auto; object-fit: contain; pointer-events: none; }
/* Upcoming event band (orange) */
.upcoming-band { background: var(--orange); color: var(--ink); }
.upcoming-copy > p { color: var(--ink); }
.upcoming-copy h2 { font-size: clamp(2rem,4.4444vw,4rem); font-weight: 300; letter-spacing: 0; text-transform: uppercase; }
.upcoming-facts { border: 0; background: #444; }
.upcoming-facts > div { background: #161614; }
.upcoming-facts span { color: #ff795f; }
.upcoming-facts strong { color: white; font-size: 15px; }
/* About */
.home-about { grid-template-columns: minmax(220px,340px) minmax(0,1fr); gap: clamp(2rem,6.7vw,6rem); }
.about-lead h2 { color: var(--accent); font-weight: 700; font-size: clamp(2rem,3.1vw,44px); max-width: 300px; }
.about-body > p,.welcome-list { font-size: 15px; line-height: 1.75; }
.welcome-block .eyebrow { color: var(--accent); }
.welcome-list { list-style: none; padding: 0; }
.welcome-list li { position: relative; padding-left: 1.5rem; }
.welcome-list li::before { content: '→'; color: var(--accent); position: absolute; left: 0; }
/* Past events summary (full list lives on past-events/) */
#past-events { background: var(--surface); border: 0; }
#past-events .section-heading { display: flex; flex-direction: row-reverse; justify-content: space-between; align-items: baseline; }
#past-events .section-heading h2 { font-size: clamp(2rem,3vw,40px); font-weight: 700; letter-spacing: -.03em; }
#past-events .section-heading div > p { display: none; }
.location-chip { min-width: 0; background: var(--paper); padding: .625rem 1rem; }
.location-chip strong { font-size: 14px; font-weight: 600; }
.location-chip span { font-size: 9px; }
/* Mailing list strip (lime) */
.mailing-section { background: var(--lime); display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; padding-inline: max(var(--page-pad), calc((100% - var(--page-width)) / 2 + var(--page-pad))); }
.mailing-section .section-heading { display: block; margin: 0; padding: 0; border: 0; }
.mailing-section h2 { color: #8f260f; font-size: clamp(1.75rem,3vw,36px); font-weight: 600; }
.mailing-section .section-heading div > p { display: none; }
.mailing-body { margin: 0; align-self: center; color: var(--ink); font-size: 15px; }
.mailing-body > p { margin: 0; }
/* A smaller copy of the mailing-list/ sign-up form. The .mailing-section prefix
 * beats the wider .signup-embed in section 6, where the shared EmailOctopus
 * overrides live too. */
.mailing-section .signup-embed { margin-top: .875rem; max-width: 340px; }
.mailing-more { margin-top: .75rem; font-size: 14px; }
.mailing-body noscript p { margin: 0; }
/* Code of conduct summary (full text lives on code-of-conduct/) */
#code-of-conduct { background: var(--surface); border: 0; }
#code-of-conduct > .page-width { display: grid; grid-template-columns: minmax(190px,.5fr) minmax(0,1fr); gap: 5rem; }
#code-of-conduct .section-heading { display: block; border: 0; padding: 0; margin: 0; }
#code-of-conduct .section-heading div > p { display: none; }
#code-of-conduct h2 { font-size: clamp(2rem,3vw,36px); line-height: 1; max-width: 220px; margin-top: .75rem; font-weight: 300; }
.coc-body { position: relative; }
.coc-body p { color: var(--accent); font-weight: 400; }
.community-shape { position: absolute; left: -4.5rem; top: 1rem; width: 70px; height: 70px; object-fit: contain; }

/* --- 5. Event page (register/) ------------------------------------------- */
/* Follows Figma frame 251:732. Speakers, sessions, and registration are not
   confirmed, so those areas keep honest "to be announced" copy in her layouts.
   Replace that copy when details are confirmed — see docs/UPDATING.md. */
.event-page { background: var(--surface); }
.event-page .section { padding-block: clamp(3.5rem,6.1vw,88px); }
/* Hero. The long rule in the title is Francisca's blank date, typed as underscores. */
.hero { padding-block: clamp(3.5rem,6.1vw,88px) clamp(3rem,5.6vw,80px); }
.hero > .eyebrow { color: #b12b14; letter-spacing: .08em; }  /* darker than Figma's orange for legibility on paper */
.hero h1 { margin: 1.5rem 0; font-size: clamp(2.6rem,5vw,72px); font-weight: 300; text-transform: uppercase; max-width: 8.7em; letter-spacing: 0; line-height: 1.08; }
.hero-summary { margin-bottom: 1.5rem; color: var(--muted); font-size: 18px; font-weight: 300; }
/* Facts strip (orange). NOTE: white on orange is ~3.3:1 — below WCAG AA. As designed; flagged with Francisca. */
.event-facts { background: var(--orange); border: 0; }
.facts-grid > div,.facts-grid > div:first-child { border: 0; padding-inline: 0; }
.event-facts span { color: #161614; font-size: 11px; letter-spacing: .06em; }
.facts-grid strong { color: #fff; font-size: 20px; font-weight: 500; }
/* Numbered section headings: "01" beside the title. */
.event-page .section-heading { grid-template-columns: auto minmax(0,1fr); column-gap: clamp(1rem,3.2vw,46px); margin-bottom: clamp(2rem,3.9vw,56px); padding-bottom: 0; border: 0; }
.event-page .section-heading > p { padding-top: .9rem; color: var(--muted); font-size: 13px; white-space: nowrap; }
.event-page .section-heading div > p { margin-top: .6rem; color: var(--muted); font-size: 16px; }
.event-page .section-heading h2 { font-weight: 700; font-size: clamp(1.75rem,4.5vw,36px); letter-spacing: 0; }
/* Keynotes: lime shape, then one card per speaker. */
.keynote-layout { display: grid; grid-template-columns: minmax(120px,210px) repeat(2,minmax(0,1fr)); gap: clamp(1.5rem,2.6vw,37px); align-items: start; }
.keynote-layout > img { width: 100%; height: 200px; object-fit: contain; transform: rotate(-110.06deg); }
.keynote-layout .keynote-card { display: block; padding: 0; background: none; border: 0; }  /* resets the older card styling in styles.css */
.keynote-card .eyebrow { font-size: 11px; }
.keynote-card h3 { margin: .6rem 0; font-size: 24px; font-weight: 700; line-height: 1.2; }
.keynote-card p { max-width: 500px; margin: 0; color: var(--muted); font-size: 15px; }
.keynote-card .button { margin-top: 1.25rem; }
/* Links inside bios ([name](url) in the CMS): ink on the grey text so they read as links. */
.keynote-card p a,.presenter-bio p a { color: var(--ink); text-decoration: underline; text-underline-offset: .2em; }
.keynote-card p a:hover,.presenter-bio p a:hover { color: var(--accent); }
/* A keynote's photo takes the next column beside its bio. The source is landscape, so crop to a tall frame on the person. */
.keynote-layout > .keynote-photo { display: block; width: 100%; max-width: 420px; height: auto; aspect-ratio: 4 / 5; object-fit: cover; object-position: 43% 30%; transform: none; }
/* Once a speaker has a photo, each speaker gets their own row: bio in the middle column, photo (if any) beside it. */
.keynote-layout:has(.keynote-photo) > .keynote-card { grid-column: 2; }
.keynote-layout:has(.keynote-photo) > .keynote-photo { grid-column: 3; }
/* Sessions: one .session-row per session (time / presenter / details). */
.session-row { display: grid; grid-template-columns: 125px 220px minmax(0,500px); gap: 28px; padding-block: 28px; border-top: 1px solid #dadad7; }
.session-row .session-time { margin: 0; color: var(--accent); font-size: 12px; letter-spacing: 0; text-transform: none; }
.session-presenter .eyebrow { font-size: 10px; }
.session-presenter strong { display: block; margin-top: 6px; font-size: 15px; font-weight: 500; }
.session-row .tag-row { margin-bottom: 10px; }
.session-row .tag-row span { padding: 5px 10px; color: var(--accent); background: #dadad7; border: 0; border-radius: 3px; font-size: 12px; letter-spacing: 0; text-transform: none; }
.session-row h3 { margin: 0 0 10px; font-size: 18px; font-weight: 700; }
.session-row p { margin: 0; color: var(--muted); font-size: 14px; }
.session-row-people { grid-template-columns: 220px minmax(0,560px); }  /* no time column: the day's timings live in the Schedule section */
/* Schedule: the day's running order with Pacific, Eastern, and (schedule.js) the visitor's own time. */
.schedule-zone { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: 0 0 1rem; font-size: 14px; }
.schedule-zone[hidden] { display: none; }
.schedule-zone select { padding: .45rem .6rem; font: inherit; color: var(--ink); background: var(--paper); border: 1px solid var(--line); border-radius: 0; }
.schedule-table { width: 100%; max-width: 1000px; border-collapse: collapse; font-size: 15px; }
.schedule-table th,.schedule-table td { padding: 14px 16px 14px 0; text-align: left; vertical-align: top; border-top: 1px solid #dadad7; }
.schedule-table thead th { padding-block: 0 10px; border-top: 0; color: var(--muted); font-family: 'Overpass Mono', monospace; font-size: 11px; font-weight: 400; letter-spacing: .07em; text-transform: uppercase; }
.schedule-table tbody th { font-weight: 700; }
.schedule-table td { color: var(--ink); white-space: nowrap; font-variant-numeric: tabular-nums; }
.schedule-table .schedule-local { color: var(--accent); }
/* Presenters: photo and name in the middle column; bios fold away under the description. */
.presenter-list { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 12px; }
.presenter-list li { display: grid; grid-template-columns: 56px minmax(0,1fr); gap: 10px; align-items: center; }
.presenter-list img,.presenter-initial { width: 56px; height: 56px; object-fit: cover; border-radius: 50%; background: #dadad7; }
.presenter-initial { display: grid; place-items: center; font-size: 20px; font-weight: 700; color: var(--accent); }
.presenter-list strong { display: block; margin: 0; font-size: 15px; font-weight: 500; }
.presenter-list strong a { color: inherit; }
.presenter-list small { display: block; color: var(--muted); font-size: 12px; }
.session-details > p + p { margin-top: 10px; }
.presenter-bio { margin-top: 10px; font-size: 14px; }
.presenter-bio summary { color: var(--accent); cursor: pointer; }
.presenter-bio p { margin-top: 6px; }
/* Registration band (lime). These rules follow the section-heading ones above on purpose. */
.registration-band { background: var(--lime); }
.registration-band .section-heading > p { color: var(--muted); }
.registration-band .section-heading h2 { color: var(--accent); }
.registration-band .section-heading div > p { color: var(--accent); font-weight: 500; }
/* Dashed box standing in for the Eventbrite widget until there is an event id. */
.embed-notice { display: grid; justify-items: center; gap: 12px; padding: clamp(1.5rem,4vw,2.5rem); text-align: center; background: rgba(45,91,255,.15); border: 1px dashed #dadad7; }
.embed-notice .eyebrow { color: #3f3f3b; font-size: 11px; }
.embed-notice h3 { margin: 0; font-size: 22px; font-weight: 700; }
.embed-notice p { max-width: 460px; margin: 0; color: var(--ink); font-size: 14px; }
/* Luma's registration form in a dialog (registration.js). Closed, the browser keeps it display:none. */
.registration-dialog { width: min(1000px, 100% - 2rem); height: min(900px, 100dvh - 2rem); max-width: none; max-height: none; padding: 0; color: var(--ink); background: var(--surface); border: 1px solid var(--ink); }
.registration-dialog[open] { display: grid; grid-template-rows: auto minmax(0,1fr) auto; }
.registration-dialog::backdrop { background: rgba(24,24,26,.6); }
.registration-dialog-bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .75rem 1rem; background: var(--lime); border-bottom: 1px solid var(--ink); }
.registration-dialog-bar .eyebrow { margin: 0; color: var(--ink); font-size: 11px; }
.registration-dialog-close { padding: .5rem 1rem; }
.registration-dialog iframe { display: block; width: 100%; height: 100%; border: 0; background: #fff; }
.registration-dialog-note { margin: 0; padding: .6rem 1rem; color: var(--muted); font-size: 13px; border-top: 1px solid var(--soft-line); }
body:has(.registration-dialog[open]) { overflow: hidden; }

/* Floating "Upcoming" reminder on every page while registration is open (event-banner.js). */
.event-banner { position: fixed; right: 1rem; bottom: 1rem; z-index: 50; display: flex; align-items: center; gap: .75rem; max-width: calc(100% - 2rem); padding: .45rem .45rem .45rem 1rem; color: var(--ink); background: var(--lime); border: 1px solid var(--ink); font-size: 14px; }
.event-banner p { margin: 0; }
.event-banner .eyebrow { display: inline; margin: 0 .4rem 0 0; color: var(--ink); font-size: 11px; }
.event-banner .button { padding: .55rem 1.1rem; white-space: nowrap; }
.event-banner-close { display: grid; place-items: center; width: 2.25rem; height: 2.25rem; padding: 0; color: var(--ink); background: none; border: 0; cursor: pointer; }
.event-banner-close[hidden] { display: none; }
.event-banner-close:focus-visible,.event-banner .button:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }
.event-banner[hidden] { display: none; }  /* its display: flex would otherwise beat the hidden attribute */
.event-banner.is-tucked { visibility: hidden; }
body:has(> .event-banner:not([hidden])) .site-footer { padding-bottom: 5.5rem; }  /* the reminder never sits on the credits */
/* Blue half-circle sitting on the history band, exported from Figma. */
.history-shape { display: flex; justify-content: center; background: var(--surface); }
.history-shape img { display: block; width: 185px; height: auto; }
.event-page .history-note { display: flex; align-items: center; min-height: 80px; padding-block: 1rem; background: #1a1a18; }
.event-page .history-note-inner p { color: #e5e5e0; font-weight: 300; }
.event-page .history-note-inner strong { color: #e5e5e0; font-size: 18px; font-weight: 700; text-transform: uppercase; }
.event-page .history-note-inner .caps { text-transform: uppercase; }
.event-page .history-note-inner b { font-weight: 400; }
.event-page .site-footer strong.logo { font-size: 16px; }

/* --- 6. Inner pages ------------------------------------------------------ */
/* events/, past-events/, mailing-list/, code-of-conduct/ — all <body class="inner-page …">. */
.inner-page { background: var(--surface); }
.hero.page-hero { padding-block: clamp(3.5rem,7vw,6rem) clamp(2.5rem,5vw,4rem); }
.hero.page-hero h1 { margin: 1rem 0 1.5rem; font-size: clamp(2.75rem,7vw,88px); font-weight: 700; line-height: 1; letter-spacing: -.03em; text-transform: none; max-width: 900px; }
.page-hero .hero-summary { max-width: 640px; color: var(--muted); }
.inner-page .section-heading h2 { font-weight: 700; font-size: clamp(1.75rem,4.5vw,36px); letter-spacing: -.02em; }
/* events/: one card per upcoming event; add .event-card-orange to feature one. */
.event-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.5rem; }
.event-card { display: grid; grid-template-columns: minmax(0,1fr) minmax(220px,300px); gap: clamp(1.5rem,4vw,3rem); padding: clamp(1.5rem,4vw,2.5rem); background: var(--paper); border: 1px solid var(--line); }
.event-card h3 { margin: .75rem 0; font-size: clamp(1.6rem,3vw,36px); font-weight: 600; line-height: 1.1; }
.event-card p { max-width: 620px; color: var(--muted); }
.event-card .button { margin-top: .5rem; }
.event-card dl { margin: 0; display: grid; gap: 1rem; align-content: start; }
.event-card dt { font-family: 'Overpass Mono', monospace; font-size: 10px; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.event-card dd { margin: .2rem 0 0; font-size: 17px; font-weight: 500; }
.event-card-orange { background: var(--orange); border-color: var(--orange); }
.event-card-orange p,.event-card-orange .eyebrow,.event-card-orange dt { color: var(--ink); }
/* past-events/: one row per event, newest first. */
.past-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.past-row { display: grid; grid-template-columns: 9rem 12rem minmax(0,1fr); gap: .25rem 2rem; align-items: baseline; padding: 1.1rem 0; border-bottom: 1px solid var(--line); }
.past-row time { font-family: 'Overpass Mono', monospace; font-size: 13px; }
.past-place { font-weight: 600; }
.past-row a,.past-title { font-size: 17px; }
.past-row a { color: var(--accent); }
/* mailing-list/: lime panel. EmailOctopus's own sign-up form loads into
 * .signup-embed when _data/site.yml supplies a form id; without JavaScript, and
 * with nothing configured, the panel asks people to email instead. */
.signup-panel { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: clamp(2rem,6vw,5rem); padding: clamp(2rem,5vw,4rem); background: var(--lime); }
.signup-panel h2 { margin: .75rem 0 1rem; color: #8f260f; font-size: clamp(1.6rem,3vw,36px); font-weight: 600; line-height: 1.1; }
.signup-panel p { color: var(--ink); }
.signup-list { margin: .75rem 0 0; padding-left: 1.25rem; display: grid; gap: .75rem; font-size: 15px; line-height: 1.6; }
.signup-note { max-width: 640px; margin-top: 1.5rem; color: var(--muted); font-size: 14px; }
.signup-embed { margin-top: 1.25rem; max-width: 420px; }
/* EmailOctopus injects its form into our page, so it takes our styling rather
 * than arriving purple. Their own custom properties are the supported hook; the
 * .signup-panel / .mailing-section prefix is only there to outweigh their
 * stylesheet, which they inject after ours. These rules cover both the panel
 * here and the homepage's smaller copy (section 4). Leave the "Powered by
 * EmailOctopus" line alone: the free plan requires it. */
.signup-panel .signup-embed .emailoctopus-form,.mailing-section .signup-embed .emailoctopus-form { --button-colour: var(--accent); --button-text-colour: #fff; --field-border-colour: var(--ink); --label-colour: var(--ink); --font-family: inherit; }
.signup-panel .signup-embed .emailoctopus-form .form-control,.signup-panel .signup-embed .emailoctopus-form input[type="submit"].btn,.mailing-section .signup-embed .emailoctopus-form .form-control,.mailing-section .signup-embed .emailoctopus-form input[type="submit"].btn { border-radius: 0; padding: .85rem 1rem; font-size: 16px; }
.signup-panel .signup-embed .emailoctopus-form input[type="submit"].btn,.mailing-section .signup-embed .emailoctopus-form input[type="submit"].btn { width: auto; padding: .85rem 1.5rem; border: 0; font-weight: 600; cursor: pointer; }
/* The homepage copy is the same form at a smaller size. */
.mailing-section .signup-embed .emailoctopus-form .form-control,.mailing-section .signup-embed .emailoctopus-form input[type="submit"].btn { padding: .6rem .75rem; font-size: 14px; }
.mailing-section .signup-embed .emailoctopus-form input[type="submit"].btn { padding: .6rem 1.1rem; }
.mailing-section .signup-embed .mastfoot { font-size: 11px; }
/* Their footer line centres itself; left-align it so the strip has one left edge. */
.mailing-section .signup-embed .text-center,.mailing-section .signup-embed .mastfoot,.mailing-section .signup-embed .mastfoot .inner { text-align: left; }
/* code-of-conduct/: sticky contents list beside long-form text. */
.coc-layout { display: grid; grid-template-columns: minmax(180px,240px) minmax(0,1fr); gap: clamp(2rem,6vw,6rem); align-items: start; }
.coc-toc { position: sticky; top: 1.5rem; }
.coc-credit { margin-top: 2.5rem; padding-top: 1rem; color: var(--muted); font-size: 14px; border-top: 1px solid var(--line); }
.coc-toc ol { list-style: none; margin: .75rem 0 0; padding: 0; display: grid; gap: .6rem; font-size: 14px; }
.prose { max-width: 780px; font-size: 16px; line-height: 1.75; }
.prose h2 { margin: 3.5rem 0 1rem; color: var(--accent); font-size: clamp(1.5rem,2.6vw,30px); font-weight: 600; line-height: 1.15; scroll-margin-top: 1.5rem; }
.prose h2:first-child { margin-top: 0; }
.prose h3 { margin: 0 0 .75rem; font-size: 18px; font-weight: 600; }
.prose ul,.prose ol { padding-left: 1.25rem; }
.prose li + li { margin-top: .5rem; }
.do-dont { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; margin-top: 1.5rem; }
.contact-card { margin: 1.5rem 0; padding: 1.5rem; background: var(--paper); border: 1px solid var(--line); }
.contact-card p { margin: .35rem 0; }
/* events/visible-java/: a camp page. Reuses the event page's orange facts band and the lime signup panel. */
.hero > .eyebrow a { color: inherit; }
.camp-intro { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,420px); gap: clamp(2rem,6vw,5rem); align-items: center; }
.camp-intro .prose h2 { margin-top: .75rem; }
.camp-intro .prose h3 { margin-top: 2rem; }
.camp-code { margin: 0; padding: 1.5rem; color: #f4f4f1; background: var(--ink); overflow-x: auto; }
.camp-code figcaption { margin-bottom: 1rem; color: var(--lime); font-family: 'Overpass Mono', monospace; font-size: 12px; }
.camp-code pre { margin: 0; font-family: 'Overpass Mono', monospace; font-size: 14px; line-height: 1.6; }
.camp-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit,minmax(220px,1fr)); gap: 1.5rem; counter-reset: step; }
.camp-steps > li { padding: 1.5rem; background: var(--paper); border: 1px solid var(--line); }
.camp-steps:not(.camp-steps-plain) > li:not(.camp-step-optional)::before { counter-increment: step; content: "Session 0" counter(step); display: block; margin-bottom: .75rem; color: var(--accent); font-family: 'Overpass Mono', monospace; font-size: 11px; letter-spacing: .07em; text-transform: uppercase; }
.camp-step-optional { border-style: dashed; }
.camp-step-optional::before { content: "Optional"; display: block; margin-bottom: .75rem; color: var(--muted); font-family: 'Overpass Mono', monospace; font-size: 11px; letter-spacing: .07em; text-transform: uppercase; }
.camp-steps h3 { margin: 0 0 .5rem; font-size: 18px; font-weight: 600; line-height: 1.25; }
.camp-steps p { margin: 0; color: var(--muted); font-size: 15px; line-height: 1.6; }
.camp-steps code { font-family: 'Overpass Mono', monospace; font-size: .9em; }
.camp-subhead { margin: 3rem 0 1.25rem; font-size: clamp(1.4rem,3vw,26px); font-weight: 600; }
.camp-facts { margin: 0; display: grid; grid-template-columns: repeat(auto-fit,minmax(260px,1fr)); border-top: 1px solid var(--line); }
.camp-facts > div { padding: 1.1rem 1.5rem 1.1rem 0; border-bottom: 1px solid var(--line); }
.camp-facts dt { font-family: 'Overpass Mono', monospace; font-size: 10px; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.camp-facts dd { margin: .3rem 0 0; font-size: 17px; font-weight: 500; }
.camp-faq { max-width: 820px; border-top: 1px solid var(--line); }
.camp-faq details { border-bottom: 1px solid var(--line); }
.camp-faq summary { padding: 1.1rem 0; font-size: 18px; font-weight: 600; cursor: pointer; }
.camp-faq details p { margin: 0 0 1.25rem; color: var(--muted); max-width: 680px; }

/* --- 7. Interactive overrides (Shristi's monogram) ----------------------- */
/* Host-side only: her artwork stays in animations.css and the scripts listed in interaction.js.
   Her stage is 95dvh tall and each mode uses all of it, so don't shorten it here (her PR #1 note). */
.anim-stage { width: 100%; border: 0; }  /* 100%, not her 100vw, which overflows beside a scrollbar */
.anim-stage-main { outline: 0; }  /* her debugging outline */
/* Her Connection layer is only as tall as its width allows, pinned to the top: at the size she recorded
   that is the whole stage, but on phones it sits under the mode buttons. Full height centres it everywhere. */
.fx-connection-canvas { width: 100%; height: 100%; }
.modes-list { inset: 1.5rem var(--page-pad) auto; justify-content: center; align-items: center; }
.modes-list > .mode-btn { font-family: Anybody, sans-serif; font-size: 12px; padding: .6rem .8rem; color: var(--ink); border: 1px solid var(--line); border-radius: 0; }
.modes-list > .mode-btn.is-active { background: var(--accent); color: white; border-color: var(--accent); }
.modes-list > .mode-btn:focus-visible { outline: 3px solid var(--ink); }
.cc-text { font-family: Anybody, sans-serif; font-size: clamp(.8rem,2vmin,1.25rem); font-weight: 500; }
.cc-text-right { color: var(--ink); }
/* Without JavaScript the mode buttons are hidden and motion is frozen. */
html:not(.js) .modes-list { display: none; }
html:not(.js) .anim-stage * { animation-play-state: paused !important; transition: none !important; }
/* Keep the static monogram visible if p5.js cannot load. */
.anim-stage:not(.canvas-ready)[data-mode="change"] .cc-path { opacity: 1; }
/* Her sketch clears to #f5f5f2, lighter than --paper; darken lets the page colour show instead of a pale box. */
.fx-change canvas { mix-blend-mode: darken; }

/* --- 8. Figma lettering hooks -------------------------------------------- */
/* The <span data-figma-run> elements are generated by scripts/sync-typography.cjs
   from design/figma-typography.json. Don't hand-edit them; see docs/TYPOGRAPHY.md. */
[data-figma-node] { font-synthesis: none; }  /* never fake a weight the font doesn't have */
[data-figma-run] { font-kerning: normal; }
.logo[data-figma-node="251:734"] { font-size: 16px; }  /* event page header logo is larger in Figma */

/* --- 9. Responsive ------------------------------------------------------- */
@media (max-width: 900px) {
 /* Homepage */
 .home-about { grid-template-columns: 1fr; }
 .upcoming-facts { max-width: 100%; }
 #code-of-conduct > .page-width { grid-template-columns: 1fr; gap: 2rem; }
 .community-shape { position: static; float: right; margin: 0 0 1rem 1rem; }
 .mailing-section { grid-template-columns: 1fr; gap: 1.5rem; }
 .site-footer { grid-template-columns: 1fr; }
 /* Shrink the half-circle smoothly, never past the left edge of the centred 480px tagline. */
 .hero-shape { --shape-w: clamp(65px, min(20vw, 50vw - 240px - 1rem), 285px); }
 /* Event page */
 .keynote-layout { grid-template-columns: 1fr 1fr; }
 .keynote-layout > img:not(.keynote-photo) { grid-column: 1 / -1; width: 140px; height: 140px; }
 .keynote-layout:has(.keynote-photo) > .keynote-card { grid-column: 1; }
 .keynote-layout:has(.keynote-photo) > .keynote-photo { grid-column: 2; }
 .session-row { grid-template-columns: 125px minmax(0,1fr); }
 .session-row .session-time { grid-column: auto; }  /* cancels a wider rule in styles.css */
 .session-row .session-details { grid-column: 1 / -1; }
 .session-row-people { grid-template-columns: minmax(0,1fr); }
 /* Inner pages */
 .event-card,.signup-panel,.coc-layout,.do-dont,.camp-intro { grid-template-columns: 1fr; }
 .coc-toc { position: static; }
}
@media (max-width: 650px) {
 /* Homepage */
 .site-header nav { gap: 0 1rem; font-size: 11px; justify-content: flex-start; }
 .site-header nav a { display: inline-flex; align-items: center; min-height: 44px; padding-block: 0; }  /* comfortable touch targets */
 .home-hero-title { font-size: 24vw; }
 .home-hero-sub { max-width: 280px; }
 .home-hero { padding-bottom: 5.5rem; }  /* room for the half-circle under the tagline */
 #past-events .section-heading { flex-direction: column; gap: .5rem; }
 /* Event page */
 .keynote-layout { grid-template-columns: 1fr; }
 .keynote-layout > img:not(.keynote-photo) { width: 110px; height: 110px; }
 .keynote-layout > .keynote-photo { max-width: 320px; }
 .keynote-layout:has(.keynote-photo) > .keynote-card,.keynote-layout:has(.keynote-photo) > .keynote-photo { grid-column: auto; }
 .session-row { display: flex; flex-direction: column; gap: .75rem; }  /* flex avoids stray grid columns */
 .event-page .section-heading { column-gap: 1rem; }
 .history-shape img { width: 120px; }
 .facts-grid { gap: 1rem; }
 .facts-grid strong { font-size: 17px; }
 .registration-dialog { width: 100%; height: 100dvh; border: 0; }  /* the whole screen on phones */
 /* Schedule rows stack: the title, then one labelled line per time zone. */
 .schedule-table thead { display: none; }
 .schedule-table tr { display: block; padding: 12px 0; border-top: 1px solid #dadad7; }
 .schedule-table th,.schedule-table td { display: block; padding: 2px 0; border: 0; white-space: normal; }
 .schedule-table td[hidden] { display: none; }
 .schedule-table td::before { content: attr(data-label) ": "; color: var(--muted); font-size: 12px; }
 .event-banner { right: .75rem; bottom: calc(.75rem + env(safe-area-inset-bottom)); left: .75rem; max-width: none; justify-content: space-between; }
 .event-banner .eyebrow,.event-banner-date { display: none; }
 /* Inner pages */
 .past-row { grid-template-columns: 1fr; }
 /* Interactive */
 .anim-stage { min-height: 540px; height: 540px; }
 .modes-list { gap: .35rem; }
 .modes-list > .mode-btn { font-size: 11px; padding: .5rem; }
 /* Too narrow for the labels inside the C gaps, so each sits just under its C, centred on it.
    The offsets are the C centres from her monogram artwork, as fractions of --mono-w. */
 .cc-text { top: calc(50% + .2882 * var(--mono-w) + .5rem); bottom: auto; transform: translateX(-50%); text-align: center; font-size: 14px; }
 .cc-text-left { left: calc(50% - .2118 * var(--mono-w)); }
 .cc-text-right { left: calc(50% + .2974 * var(--mono-w)); right: auto; }
}

/* --- 10. Reduced motion -------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
 .anim-stage *, .anim-stage *::before, .anim-stage *::after { animation: none !important; transition: none !important; }
 .anim-stage-main[data-mode="creative-commons"] { clip-path: none; }
 /* interaction.js stops the p5 canvas, so Change shows the static monogram; no confetti; the scribble shows finished. */
 .anim-stage[data-mode="change"] .cc-path { opacity: 1; }
 .fx-change,.fx-confetti { display: none !important; }
 .anim-stage .cc-scribble { mask: none; }
}
