/* ============================================================ Roman Felden — Portfolio Design : minimalisme éditorial Serif display (Fraunces) + Sans (Inter) + Mono (IBM Plex Mono) ============================================================ */ /* ---------- Tokens ---------- */ :root { --paper: #faf9f5; --paper-raised: #ffffff; --ink: #191713; --ink-soft: #44403a; --muted: #80796e; --hairline: #e6e2d8; --hairline-strong: #d5d0c4; --accent: #c2481d; --accent-soft: rgba(194, 72, 29, 0.08); --selection: rgba(194, 72, 29, 0.18); --font-serif: "Fraunces", Georgia, serif; --font-sans: "Inter", -apple-system, BlinkMacSystemFont, sans-serif; --font-mono: "IBM Plex Mono", "SFMono-Regular", Consolas, monospace; --container: 68rem; --gutter: clamp(1.25rem, 4vw, 2.5rem); --section-gap: clamp(4.5rem, 10vw, 8rem); --ease-out: cubic-bezier(0.22, 1, 0.36, 1); --nav-h: 4.5rem; } [data-theme="dark"] { --paper: #14120f; --paper-raised: #1c1a16; --ink: #ece8e0; --ink-soft: #c8c2b6; --muted: #8f887b; --hairline: #2b2822; --hairline-strong: #3b372f; --accent: #e8734a; --accent-soft: rgba(232, 115, 74, 0.12); --selection: rgba(232, 115, 74, 0.3); } /* ---------- Reset ---------- */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } html { scroll-behavior: smooth; scroll-padding-top: calc(var(--nav-h) + 1rem); } body { font-family: var(--font-sans); font-size: 1rem; line-height: 1.65; color: var(--ink); background: var(--paper); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; transition: background-color 0.35s ease, color 0.35s ease; } ::selection { background: var(--selection); color: var(--ink); } img, svg { display: block; } a { color: inherit; text-decoration: none; } ul, ol { list-style: none; } button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; } /* ---------- Utilities ---------- */ .container { max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); } .mono-label { font-family: var(--font-mono); font-size: 0.72rem; font-weight: 500; letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); } .hairline-top { border-top: 1px solid var(--hairline); } /* Animated underline link */ .u-link { position: relative; color: var(--ink); background-image: linear-gradient(currentColor, currentColor); background-size: 0% 1px; background-position: 0 100%; background-repeat: no-repeat; transition: background-size 0.35s var(--ease-out), color 0.2s ease; } .u-link:hover { background-size: 100% 1px; } .u-link--accent { color: var(--accent); } /* ---------- Scroll reveal ---------- */ .reveal { opacity: 0; transform: translateY(22px); transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out); transition-delay: var(--reveal-delay, 0s); } .reveal.is-visible { opacity: 1; transform: none; } @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } .reveal { opacity: 1; transform: none; transition: none; } *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } } /* ============================================================ NAVBAR ============================================================ */ .navbar { position: fixed; inset: 0 0 auto 0; z-index: 100; height: var(--nav-h); background: color-mix(in srgb, var(--paper) 82%, transparent); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); border-bottom: 1px solid var(--hairline); transition: background-color 0.35s ease; } .navbar-container { max-width: var(--container); height: 100%; margin-inline: auto; padding-inline: var(--gutter); display: flex; align-items: center; justify-content: space-between; gap: 1rem; } .navbar-brand { display: flex; align-items: baseline; gap: 0.6rem; } .navbar-brand .brand-name { font-family: var(--font-serif); font-size: 1.15rem; font-weight: 600; letter-spacing: 0.01em; white-space: nowrap; } .navbar-brand .brand-dot { color: var(--accent); } .navbar-brand .brand-tag { font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); } .navbar-menu { display: flex; align-items: center; gap: clamp(1rem, 3vw, 2rem); } .navbar-menu a { position: relative; font-size: 0.92rem; font-weight: 500; color: var(--ink-soft); padding: 0.25rem 0; transition: color 0.2s ease; } .navbar-menu a::after { content: ""; position: absolute; left: 0; bottom: -2px; width: 100%; height: 1px; background: var(--accent); transform: scaleX(0); transform-origin: left; transition: transform 0.3s var(--ease-out); } .navbar-menu a:hover, .navbar-menu a.active { color: var(--ink); } .navbar-menu a:hover::after, .navbar-menu a.active::after { transform: scaleX(1); } .navbar-menu .nav-index { font-family: var(--font-mono); font-size: 0.66rem; color: var(--muted); margin-right: 0.35rem; } /* Theme toggle */ .theme-toggle { display: inline-flex; align-items: center; justify-content: center; width: 2.25rem; height: 2.25rem; border: 1px solid var(--hairline-strong); border-radius: 50%; color: var(--ink-soft); transition: color 0.2s ease, border-color 0.2s ease, transform 0.4s var(--ease-out); } .theme-toggle:hover { color: var(--accent); border-color: var(--accent); transform: rotate(40deg); } .theme-toggle svg { width: 1.05rem; height: 1.05rem; } /* ============================================================ BUTTONS ============================================================ */ .btn { display: inline-flex; align-items: center; gap: 0.6rem; font-size: 0.95rem; font-weight: 550; padding: 0.85rem 1.6rem; border-radius: 999px; border: 1px solid var(--ink); transition: all 0.25s var(--ease-out); } .btn svg { width: 1rem; height: 1rem; transition: transform 0.25s var(--ease-out); } .btn-primary { background: var(--ink); color: var(--paper); } .btn-primary:hover { background: var(--accent); border-color: var(--accent); color: #fff; } .btn-primary:hover svg { transform: translateX(3px); } .btn-outline { background: transparent; color: var(--ink); border-color: var(--hairline-strong); } .btn-outline:hover { border-color: var(--ink); } .btn-outline:hover svg { transform: translateX(3px); } /* ============================================================ HERO (index) ============================================================ */ .hero { min-height: 92svh; display: flex; align-items: center; padding-top: var(--nav-h); position: relative; } .hero-grid { display: grid; grid-template-columns: 1fr; gap: 2.5rem; width: 100%; } .hero-meta { display: flex; align-items: center; gap: 1rem; } .hero-meta .rule { flex: 0 0 3rem; height: 1px; background: var(--accent); } .hero-name { font-family: var(--font-serif); font-size: clamp(3rem, 9vw, 6.5rem); font-weight: 560; line-height: 1.02; letter-spacing: -0.02em; } .hero-name em { font-style: italic; font-weight: 400; color: var(--accent); } .hero-role { font-family: var(--font-serif); font-size: clamp(1.25rem, 3vw, 1.9rem); font-weight: 400; font-style: italic; color: var(--ink-soft); max-width: 34ch; line-height: 1.35; } .hero-desc { color: var(--muted); max-width: 46ch; font-size: 1.02rem; } .hero-actions { display: flex; flex-wrap: wrap; gap: 0.9rem; margin-top: 0.5rem; } .hero-foot { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-top: clamp(2.5rem, 6vw, 4.5rem); padding-top: 1.25rem; border-top: 1px solid var(--hairline); } .hero-foot .mono-label { display: inline-flex; align-items: center; gap: 0.5rem; } .status-dot { width: 7px; height: 7px; border-radius: 50%; background: #3d9a50; box-shadow: 0 0 0 3px rgba(61, 154, 80, 0.18); animation: pulse 2.4s ease-in-out infinite; } @keyframes pulse { 0%, 100% { box-shadow: 0 0 0 3px rgba(61, 154, 80, 0.18); } 50% { box-shadow: 0 0 0 6px rgba(61, 154, 80, 0.06); } } /* ============================================================ SECTIONS (commun) ============================================================ */ .section { padding-block: var(--section-gap); border-top: 1px solid var(--hairline); } .section-head { display: grid; grid-template-columns: auto 1fr; align-items: baseline; gap: clamp(1rem, 4vw, 2.5rem); margin-bottom: clamp(2.5rem, 6vw, 4rem); } .section-number { font-family: var(--font-mono); font-size: 0.8rem; color: var(--accent); letter-spacing: 0.1em; } .section-title { font-family: var(--font-serif); font-size: clamp(2rem, 5vw, 3.25rem); font-weight: 560; letter-spacing: -0.015em; line-height: 1.1; } .section-title em { font-style: italic; font-weight: 400; color: var(--accent); } .section-sub { grid-column: 2; color: var(--muted); max-width: 52ch; margin-top: -1.5rem; } /* ============================================================ INDEX — À propos ============================================================ */ .about-grid { display: grid; grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--hairline); border-left: 1px solid var(--hairline); } .about-cell { padding: clamp(1.5rem, 3.5vw, 2.5rem); border-right: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); display: flex; flex-direction: column; gap: 0.9rem; transition: background-color 0.3s ease; } .about-cell:hover { background: var(--accent-soft); } .about-cell .cell-label { font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); } .about-cell h3 { font-family: var(--font-serif); font-size: 1.35rem; font-weight: 560; letter-spacing: -0.01em; } .about-cell p { color: var(--muted); font-size: 0.95rem; } /* ============================================================ INDEX — Compétences (liste éditoriale) ============================================================ */ .skill-rows { border-top: 1px solid var(--hairline); } .skill-row { display: grid; grid-template-columns: 3rem 1fr 2fr; align-items: baseline; gap: clamp(1rem, 4vw, 2.5rem); padding: 1.75rem 0; border-bottom: 1px solid var(--hairline); transition: padding-left 0.3s var(--ease-out); } .skill-row:hover { padding-left: 0.75rem; } .skill-row .row-index { font-family: var(--font-mono); font-size: 0.75rem; color: var(--muted); } .skill-row h3 { font-family: var(--font-serif); font-size: clamp(1.3rem, 2.5vw, 1.7rem); font-weight: 560; letter-spacing: -0.01em; } .skill-row .row-tags { display: flex; flex-wrap: wrap; gap: 0.45rem; } .tag { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.03em; color: var(--ink-soft); border: 1px solid var(--hairline-strong); border-radius: 999px; padding: 0.28rem 0.75rem; white-space: nowrap; transition: all 0.2s ease; } .tag:hover { border-color: var(--accent); color: var(--accent); } /* ============================================================ INDEX / PROJETS — cartes projet ============================================================ */ .project-list { border-top: 1px solid var(--hairline); } .project-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: clamp(1.25rem, 4vw, 3rem); padding: clamp(1.75rem, 4vw, 2.75rem) 0; border-bottom: 1px solid var(--hairline); position: relative; transition: padding-left 0.35s var(--ease-out); } .project-row:hover { padding-left: 1rem; } .project-row .p-index { font-family: var(--font-serif); font-size: clamp(1.5rem, 3.5vw, 2.5rem); font-style: italic; font-weight: 400; color: var(--hairline-strong); transition: color 0.3s ease; min-width: 3.5rem; } .project-row:hover .p-index { color: var(--accent); } .project-row .p-body { display: flex; flex-direction: column; gap: 0.4rem; } .project-row h3 { font-family: var(--font-serif); font-size: clamp(1.5rem, 3.5vw, 2.25rem); font-weight: 560; letter-spacing: -0.015em; line-height: 1.15; } .project-row .p-desc { color: var(--muted); max-width: 56ch; font-size: 0.97rem; } .project-row .p-tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; } .project-row .p-arrow { width: 2.75rem; height: 2.75rem; border: 1px solid var(--hairline-strong); border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: var(--ink-soft); transition: all 0.3s var(--ease-out); flex-shrink: 0; } .project-row .p-arrow svg { width: 1.1rem; height: 1.1rem; transition: transform 0.3s var(--ease-out); } .project-row:hover .p-arrow { background: var(--accent); border-color: var(--accent); color: #fff; } .project-row:hover .p-arrow svg { transform: rotate(-45deg); } /* Lien étendu sur toute la ligne */ .project-row a.p-stretch::after { content: ""; position: absolute; inset: 0; } /* ============================================================ PAGE HEADER (pages internes) ============================================================ */ .page-head { padding-top: calc(var(--nav-h) + clamp(3rem, 8vw, 6rem)); padding-bottom: clamp(2.5rem, 6vw, 4rem); } .page-head .hero-meta { margin-bottom: 1.5rem; } .page-title { font-family: var(--font-serif); font-size: clamp(2.75rem, 7vw, 5rem); font-weight: 560; letter-spacing: -0.02em; line-height: 1.04; } .page-title em { font-style: italic; font-weight: 400; color: var(--accent); } .page-sub { margin-top: 1.25rem; color: var(--muted); max-width: 54ch; font-size: 1.05rem; } /* ============================================================ CV ============================================================ */ .cv-layout { display: grid; grid-template-columns: 16rem 1fr; gap: clamp(2rem, 6vw, 5rem); padding-bottom: var(--section-gap); } .cv-aside { display: flex; flex-direction: column; gap: 2.25rem; } .cv-aside-block .mono-label { display: block; margin-bottom: 0.9rem; padding-bottom: 0.6rem; border-bottom: 1px solid var(--hairline); } .cv-contact-list { display: flex; flex-direction: column; gap: 0.55rem; font-size: 0.92rem; color: var(--ink-soft); } .cv-contact-list a { color: var(--ink); } .cv-contact-list .c-key { font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); display: block; } .cv-lang { display: flex; justify-content: space-between; align-items: baseline; padding: 0.45rem 0; border-bottom: 1px dashed var(--hairline); font-size: 0.95rem; } .cv-lang span:last-child { font-family: var(--font-mono); font-size: 0.72rem; color: var(--muted); } .cv-interest-tags { display: flex; flex-wrap: wrap; gap: 0.4rem; } .cv-main { display: flex; flex-direction: column; gap: var(--section-gap); } .cv-block-head { display: flex; align-items: baseline; gap: 1rem; margin-bottom: 2rem; } .cv-block-head .section-number { flex-shrink: 0; } .cv-block-head h2 { font-family: var(--font-serif); font-size: clamp(1.6rem, 3.5vw, 2.2rem); font-weight: 560; letter-spacing: -0.015em; } /* Timeline expériences */ .timeline { position: relative; padding-left: 1.75rem; } .timeline::before { content: ""; position: absolute; left: 4px; top: 8px; bottom: 8px; width: 1px; background: var(--hairline-strong); } .timeline-item { position: relative; padding-bottom: 2.5rem; } .timeline-item:last-child { padding-bottom: 0; } .timeline-item::before { content: ""; position: absolute; left: -1.75rem; top: 8px; width: 9px; height: 9px; border-radius: 50%; background: var(--paper); border: 2px solid var(--hairline-strong); transition: border-color 0.25s ease, background 0.25s ease; } .timeline-item:hover::before { border-color: var(--accent); background: var(--accent); } .timeline-item.current::before { border-color: var(--accent); background: var(--accent); } .t-header { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.35rem 1rem; } .t-header h3 { font-family: var(--font-serif); font-size: 1.3rem; font-weight: 560; letter-spacing: -0.01em; } .t-date { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--accent); border: 1px solid var(--accent); border-radius: 999px; padding: 0.2rem 0.7rem; white-space: nowrap; } .t-company { font-weight: 550; color: var(--ink-soft); margin-top: 0.15rem; } .t-location { font-family: var(--font-mono); font-size: 0.72rem; color: var(--muted); margin-top: 0.1rem; } .t-list { margin-top: 0.75rem; display: flex; flex-direction: column; gap: 0.4rem; color: var(--muted); font-size: 0.95rem; } .t-list li { position: relative; padding-left: 1.1rem; } .t-list li::before { content: "—"; position: absolute; left: 0; color: var(--accent); } /* Formation */ .edu-list { border-top: 1px solid var(--hairline); } .edu-item { display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: 0.5rem 1.5rem; padding: 1.35rem 0; border-bottom: 1px solid var(--hairline); transition: padding-left 0.3s var(--ease-out); } .edu-item:hover { padding-left: 0.75rem; } .edu-item h3 { font-family: var(--font-serif); font-size: 1.2rem; font-weight: 560; } .edu-item .edu-degree { grid-column: 1; color: var(--muted); font-size: 0.95rem; } .edu-item .edu-date { grid-column: 2; grid-row: 1 / span 2; font-family: var(--font-mono); font-size: 0.75rem; color: var(--muted); white-space: nowrap; align-self: center; } /* Compétences CV */ .cv-skills { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.5rem, 4vw, 2.5rem); } .cv-skill-cat h3 { font-family: var(--font-serif); font-size: 1.15rem; font-weight: 560; padding-bottom: 0.6rem; margin-bottom: 0.9rem; border-bottom: 1px solid var(--hairline); } .cv-skill-cat .row-tags { display: flex; flex-wrap: wrap; gap: 0.4rem; } /* ============================================================ PROJETS — détail ============================================================ */ .project-detail { padding-block: var(--section-gap); border-top: 1px solid var(--hairline); } .project-detail-grid { display: grid; grid-template-columns: 1fr 1.6fr; gap: clamp(2rem, 6vw, 5rem); } .pd-sticky { position: sticky; top: calc(var(--nav-h) + 2rem); align-self: start; display: flex; flex-direction: column; gap: 1rem; } .pd-index { font-family: var(--font-mono); font-size: 0.8rem; color: var(--accent); letter-spacing: 0.1em; } .pd-title { font-family: var(--font-serif); font-size: clamp(2rem, 4.5vw, 3rem); font-weight: 560; letter-spacing: -0.02em; line-height: 1.08; } .pd-subtitle { font-family: var(--font-serif); font-style: italic; color: var(--muted); font-size: 1.1rem; } .pd-tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; } .pd-body > p { color: var(--ink-soft); font-size: 1.02rem; max-width: 60ch; margin-bottom: 2.5rem; } .pd-features { display: flex; flex-direction: column; border-top: 1px solid var(--hairline); } .pd-feature { display: grid; grid-template-columns: auto 1fr; gap: 1.25rem; padding: 1.4rem 0; border-bottom: 1px solid var(--hairline); } .pd-feature .f-num { font-family: var(--font-mono); font-size: 0.72rem; color: var(--muted); padding-top: 0.3rem; } .pd-feature h4 { font-family: var(--font-serif); font-size: 1.15rem; font-weight: 560; margin-bottom: 0.25rem; } .pd-feature p { color: var(--muted); font-size: 0.95rem; } .pd-stack { margin-top: 2.25rem; } .pd-stack .mono-label { display: block; margin-bottom: 0.85rem; } .pd-stack .row-tags { display: flex; flex-wrap: wrap; gap: 0.45rem; } /* ============================================================ FOOTER ============================================================ */ .footer { border-top: 1px solid var(--hairline); padding: 3rem 0 2.5rem; } .footer-grid { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 1.25rem; } .footer .footer-name { font-family: var(--font-serif); font-size: 1.05rem; font-weight: 560; } .footer .footer-name .brand-dot { color: var(--accent); } .footer-links { display: flex; gap: 1.5rem; font-size: 0.9rem; color: var(--muted); } .footer-links a:hover { color: var(--accent); } .footer-bottom { margin-top: 2rem; padding-top: 1.25rem; border-top: 1px dashed var(--hairline); display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.75rem; font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.08em; color: var(--muted); } /* ============================================================ RESPONSIVE ============================================================ */ @media (max-width: 900px) { .about-grid { grid-template-columns: 1fr; } .skill-row { grid-template-columns: 2rem 1fr; } .skill-row .row-tags { grid-column: 2; margin-top: 0.6rem; } .cv-layout { grid-template-columns: 1fr; } .cv-aside { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 2rem; padding-bottom: 2rem; border-bottom: 1px solid var(--hairline); } .cv-skills { grid-template-columns: 1fr; } .project-detail-grid { grid-template-columns: 1fr; } .pd-sticky { position: static; } } @media (max-width: 640px) { .navbar-menu { gap: 0.9rem; } .navbar-menu .nav-index { display: none; } .navbar-brand .brand-tag { display: none; } .project-row { grid-template-columns: auto 1fr; } .project-row .p-arrow { display: none; } .hero-foot { flex-direction: column; align-items: flex-start; gap: 0.5rem; } .section-head { grid-template-columns: 1fr; gap: 0.5rem; } .section-sub { grid-column: 1; margin-top: 0; } }