Redesign homepage: navy and pink 'sentence is the layout' direction

Complete rebuild of the single page from the design-taste-frontend skill
(direction: sentence-as-layout, seed 1084447843). CSS and JS moved out of
the markup into css/site.css and js/site.js.

- navy field #1a2039 with pink ink #f9a3c0: no Odoo plum, no teal, no violet
- hero headline carries a 1689 world map inside the sentence
- claims as full-bleed switchable bands, tips table, module picker
- four archival Wikimedia pictures, credited in the footer
- inspector: 0 FAIL at 1440 / 768 / 390 (lint clean)
This commit is contained in:
Oliver committed 2026-10-23 14:26:27 +00:00
1 parent ed6d3c747b
commit 94eb541ac3
9 files changed
+1192 -790

No files matched your search

+735
View File
@@ -0,0 +1,735 @@
/* ============================================================
The OC Guy — Odoo Community tips and tricks
Direction: "the sentence is the layout" (seed 1084447843)
Palette: navy field, pink ink. No Odoo plum, no teal, no violet.
============================================================ */
:root {
/* colour roles */
--bg: #1a2039;
--surface: #212846;
--ink: #f9a3c0;
--muted: #b9879c;
--accent: #f9a3c0;
--accent-ink: #1a2039;
/* type steps — five, no more */
--t-small: clamp(13px, 0.8rem + 0.1vw, 14px);
--t-body: clamp(17px, 1rem + 0.25vw, 19px);
--t-statement: clamp(26px, 2.35vw, 36px);
--t-head: clamp(32px, 1.3rem + 3.2vw, 64px);
--t-display: clamp(38px, 6.1vw, 90px);
--pad: clamp(16px, 3vw, 32px);
--gap-section: clamp(72px, 7.5vw, 112px);
--font: "General Sans", ui-sans-serif, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
--ease: cubic-bezier(0.2, 0.8, 0.2, 1);
}
*, *::before, *::after { box-sizing: border-box; }
html {
-webkit-text-size-adjust: 100%;
scroll-behavior: smooth;
}
body {
margin: 0;
background: var(--bg);
color: var(--ink);
font-family: var(--font);
font-size: var(--t-body);
line-height: 1.45;
font-weight: 400;
overflow-x: hidden;
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }
button, input { font: inherit; color: inherit; }
:focus-visible {
outline: 2px solid var(--ink);
outline-offset: 4px;
}
::selection { background: var(--ink); color: var(--bg); }
.sr-only {
position: absolute; width: 1px; height: 1px;
padding: 0; margin: -1px; overflow: hidden;
clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
position: fixed; top: 8px; left: 8px; z-index: 60;
padding: 10px 14px; background: var(--ink); color: var(--bg);
font-size: var(--t-small); text-decoration: none;
transform: translateY(-160%);
transition: transform 240ms var(--ease);
}
.skip:focus { transform: translateY(0); }
/* ---------- top bar: wordmark left, links spread right ---------- */
.topbar {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 24px;
padding: 24px var(--pad) 0;
}
.mark {
font-size: var(--t-small);
font-weight: 500;
text-decoration: none;
letter-spacing: -0.01em;
}
.nav {
display: flex;
flex-wrap: wrap;
gap: clamp(12px, 2.4vw, 40px);
font-size: var(--t-small);
}
.nav a { text-decoration: none; color: var(--muted); }
.nav a:hover, .nav a:focus-visible { color: var(--ink); }
.nav .nav-action { color: var(--ink); }
/* ---------- hero ---------- */
.hero {
min-height: 92svh;
display: flex;
flex-direction: column;
justify-content: center;
padding: clamp(56px, 9vh, 110px) var(--pad) 32px;
}
.hero-part { white-space: nowrap; }
.hero-line {
margin: 0;
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 0 0.2em;
font-size: var(--t-display);
font-weight: 700;
letter-spacing: -0.035em;
line-height: 0.94;
}
/* the photograph set into the sentence, one line tall */
.slot {
display: inline-block;
width: 2.8em;
height: 0.76em;
vertical-align: 0;
overflow: hidden;
background: var(--surface);
}
.slot img {
width: 100%; height: 100%;
object-fit: cover;
object-position: 50% 52%;
}
.hero-foot {
margin-top: clamp(40px, 7vh, 88px);
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: var(--pad);
align-items: end;
}
.hero-say {
grid-column: 5 / 11;
margin: 0;
max-width: 34em;
font-size: var(--t-body);
line-height: 1.5;
}
.hero-foot .btn { grid-column: 11 / 13; justify-self: end; }
/* ---------- buttons: one shape, square, filled ---------- */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 48px;
padding: 0 26px;
background: var(--accent);
color: var(--accent-ink);
font-size: var(--t-small);
font-weight: 500;
text-decoration: none;
border: 0;
border-radius: 0;
cursor: pointer;
transition: transform 200ms var(--ease), background-color 200ms var(--ease);
}
.btn:hover { background: var(--ink); transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
/* ---------- intro: statement with inline thumbnails ---------- */
.intro {
padding: clamp(56px, 6vw, 96px) var(--pad) clamp(80px, 9vw, 144px);
display: flex;
justify-content: center;
}
.statement {
margin: 0;
max-width: 21em;
font-size: var(--t-statement);
line-height: 1.18;
letter-spacing: -0.015em;
font-weight: 500;
}
.thumb {
display: inline-block;
width: 1.7em;
height: 1em;
margin: 0 0.12em;
vertical-align: -0.1em;
overflow: hidden;
border-radius: 0.06em;
background: var(--surface);
}
.thumb img { width: 100%; height: 100%; object-fit: cover; }
.thumb img { object-position: 50% 40%; }
/* ---------- open: map to full width ---------- */
.open { padding-bottom: var(--gap-section); overflow: clip; }
.map-figure { margin: 0; overflow: clip; }
.map-figure img {
width: 100%;
max-width: 100%;
height: clamp(220px, 30vw, 420px);
object-fit: cover;
object-position: 50% 45%;
background: var(--surface);
}
.map-figure figcaption {
padding: 14px var(--pad) 0;
font-size: var(--t-small);
color: var(--muted);
max-width: 52em;
}
.open-copy {
margin-top: clamp(48px, 6vw, 88px);
padding: 0 var(--pad);
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: var(--pad);
}
.open-copy h2 {
grid-column: 1 / 7;
margin: 0;
font-size: var(--t-head);
font-weight: 700;
letter-spacing: -0.03em;
line-height: 0.98;
}
.open-copy p {
grid-column: 8 / 13;
margin: 0;
max-width: 30em;
line-height: 1.55;
}
.open-figure {
grid-column: 10 / 13;
margin: clamp(32px, 4vw, 56px) 0 0;
}
.open-figure img {
width: 100%;
aspect-ratio: 4 / 5;
object-fit: cover;
object-position: 50% 38%;
background: var(--surface);
}
/* ---------- claims: sentences with switches ---------- */
.claims {
background: var(--surface);
padding: clamp(24px, 3vw, 40px) 0 calc(var(--gap-section) * 0.6);
}
.band {
border: 0;
background: transparent;
transition: background-color 400ms var(--ease);
padding: 0 var(--pad);
}
.band[data-on="true"] { background: var(--bg); }
.band-switch {
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
gap: 24px;
width: 100%;
min-height: clamp(112px, 17vh, 168px);
padding: 18px 0;
background: none;
border: 0;
text-align: left;
cursor: pointer;
}
.band-text {
font-size: var(--t-statement);
font-weight: 500;
letter-spacing: -0.03em;
line-height: 1;
color: var(--muted);
transition: color 300ms var(--ease);
}
.band[data-on="true"] .band-text { color: var(--ink); }
.track {
position: relative;
display: block;
width: 2.4em;
height: 1.15em;
min-width: 52px;
min-height: 26px;
background: var(--bg);
transition: background-color 300ms var(--ease);
}
.band[data-on="true"] .track { background: var(--ink); }
.knob {
position: absolute;
top: 0.14em;
left: 0.14em;
width: calc(1.15em - 0.28em);
height: calc(1.15em - 0.28em);
min-width: 18px;
min-height: 18px;
background: var(--muted);
transition: transform 300ms var(--ease), background-color 300ms var(--ease);
}
.band[data-on="true"] .knob {
transform: translateX(1.25em);
background: var(--bg);
}
.band-value {
margin: 0;
max-width: 46em;
padding: 0 0 22px;
font-size: var(--t-body);
line-height: 1.5;
color: var(--muted);
opacity: 0.6;
transition: opacity 300ms var(--ease), color 300ms var(--ease);
}
.band[data-on="true"] .band-value { opacity: 1; color: var(--ink); }
.band-value code {
font-family: var(--font);
font-weight: 500;
color: var(--ink);
}
/* ---------- tips: statement left, table pushed right ---------- */
.tips { padding: var(--gap-section) 0; }
.tips h2 {
margin: 0 0 96px;
padding-left: var(--pad);
padding-right: var(--pad);
font-size: var(--t-head);
font-weight: 700;
letter-spacing: -0.035em;
line-height: 0.96;
max-width: 15em;
}
.tips h2::first-line { padding-left: 3vw; }
.tips-grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: var(--pad);
padding: 0 var(--pad);
}
.tips-side { grid-column: 1 / 6; }
.tips-note {
margin: 0 0 40px;
max-width: 24em;
color: var(--muted);
line-height: 1.55;
}
/* the live thing */
.picker {
background: var(--surface);
padding: clamp(18px, 2vw, 28px);
max-width: 30em;
}
.picker-q {
margin: 0 0 16px;
font-size: var(--t-small);
color: var(--muted);
}
.chips {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.chip {
padding: 10px 14px;
min-height: 40px;
background: var(--bg);
color: var(--ink);
border: 0;
border-radius: 0;
font-size: var(--t-small);
cursor: pointer;
transition: background-color 180ms var(--ease), color 180ms var(--ease), transform 180ms var(--ease);
}
.chip:hover { transform: translateY(-1px); }
.chip[aria-pressed="true"] { background: var(--ink); color: var(--bg); }
.picker-out {
margin: 20px 0 0;
font-size: var(--t-body);
line-height: 1.4;
min-height: 2.8em;
color: var(--ink);
}
.picker-out .mod { font-weight: 700; }
.picker-out .arrow { color: var(--muted); }
.tips-figure {
margin: clamp(28px, 4vw, 48px) 0 0;
width: min(100%, 22em);
}
.tips-figure img {
width: 100%;
aspect-ratio: 4 / 5;
object-fit: cover;
object-position: 50% 42%;
background: var(--surface);
}
.tips-list {
grid-column: 8 / 13;
margin: 0;
padding: 0;
list-style: none;
}
.tips-list li {
display: grid;
grid-template-columns: 7.5em 1fr;
gap: 4px 16px;
padding-bottom: 26px;
font-size: var(--t-body);
}
.tips-list li:nth-child(4) { padding-top: 18px; }
.tip-kind { color: var(--muted); font-size: var(--t-small); padding-top: 3px; }
.tip-what { line-height: 1.35; }
.tip-where {
grid-column: 2;
color: var(--muted);
font-size: var(--t-small);
text-decoration: none;
}
a.tip-where { color: var(--ink); text-underline-offset: 3px; text-decoration: underline; }
a.tip-where:hover { color: var(--bg); background: var(--ink); }
/* ---------- about: portrait as drop cap ---------- */
.about {
padding: var(--gap-section) var(--pad);
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-areas:
"head head head head head head head head head head head head"
"bio bio bio bio bio bio bio bio bio . . ."
"facts facts facts facts . . . . . . . .";
gap: 0 var(--pad);
}
.about-facts {
grid-area: facts;
margin: 40px 0 0;
max-width: 32em;
display: flex;
flex-direction: column;
gap: 10px;
font-size: var(--t-small);
color: var(--muted);
}
.about-facts a { color: var(--ink); }
.about h2 {
grid-area: head;
margin: 0 0 28px;
font-size: var(--t-head);
font-weight: 700;
letter-spacing: -0.03em;
line-height: 1;
}
.bio {
grid-area: bio;
margin: 0;
max-width: 26em;
font-size: var(--t-statement);
line-height: 1.22;
letter-spacing: -0.01em;
font-weight: 400;
}
.dropcap {
float: left;
width: 5em;
height: 5em;
margin: 0.1em 0.5em 0.2em 0;
object-fit: cover;
object-position: 30% 40%;
background: var(--surface);
}
/* ---------- ask: a sentence with a blank ---------- */
.ask {
background: var(--surface);
padding: var(--gap-section) var(--pad);
max-width: 100%;
}
.ask-line {
margin: 0;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.22em;
font-size: var(--t-head);
font-weight: 700;
letter-spacing: -0.03em;
line-height: 1.1;
}
.ask-line label { flex: 0 0 auto; }
.ask-line input {
flex: 1 1 7em;
min-width: 6em;
height: 1.2em;
padding: 0 0.2em;
background: var(--surface);
border: 0;
border-radius: 0;
font-size: 0.5em;
font-weight: 500;
letter-spacing: 0;
}
.ask-line input::placeholder { color: var(--muted); }
.ask-send {
flex: 0 0 auto;
height: 1.05em;
padding: 0 0.4em;
background: var(--accent);
color: var(--accent-ink);
border: 0;
border-radius: 0;
font-size: 0.5em;
font-weight: 500;
letter-spacing: 0;
cursor: pointer;
transition: background-color 180ms var(--ease), transform 180ms var(--ease);
}
.ask-send:hover { background: var(--ink); transform: translateY(-1px); }
.ask-note {
margin: 28px 0 0;
font-size: var(--t-small);
color: var(--muted);
max-width: 40em;
}
/* ---------- footer: invitation over a cropped name ---------- */
.foot {
background: var(--ink);
color: var(--bg);
padding: clamp(56px, 7vw, 96px) var(--pad) 0;
overflow: hidden;
min-height: 88svh;
display: flex;
flex-direction: column;
}
.foot-top {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: var(--pad);
align-items: start;
}
.foot-invite {
grid-column: 1 / 8;
margin: 0;
font-size: var(--t-head);
font-weight: 700;
letter-spacing: -0.035em;
line-height: 0.98;
max-width: 12em;
}
.foot-top .btn {
grid-column: 10 / 13;
justify-self: end;
background: var(--bg);
color: var(--ink);
}
.foot-top .btn:hover { background: var(--surface); color: var(--ink); }
.foot-links {
margin-top: clamp(40px, 6vw, 80px);
display: flex;
flex-wrap: wrap;
gap: 24px;
font-size: var(--t-body);
}
.foot-links a { text-decoration: underline; text-underline-offset: 4px; }
.foot-links a:hover { text-decoration-thickness: 2px; }
.foot-credits {
margin: 24px 0 0;
font-size: var(--t-small);
line-height: 1.5;
max-width: 62em;
opacity: 0.9;
}
.foot-credits a { text-underline-offset: 2px; }
.foot-name {
margin: auto 0 0;
font-size: clamp(64px, 20vw, 280px);
font-weight: 700;
letter-spacing: -0.05em;
line-height: 0.8;
white-space: nowrap;
transform: translateY(22%);
user-select: none;
}
/* ---------- motion ---------- */
html.js [data-rv] {
opacity: 0;
transform: translateY(22px);
transition: opacity 620ms var(--ease), transform 620ms var(--ease);
}
html.js [data-rv].rv-in { opacity: 1; transform: none; }
html.js [data-rv="2"] { transition-delay: 70ms; }
html.js [data-rv="3"] { transition-delay: 140ms; }
html.js [data-rv="4"] { transition-delay: 210ms; }
/* signature move: the shutter on the hero photograph */
html.js .slot { clip-path: inset(0 100% 0 0); }
html.js .hero-line.shutter .slot {
clip-path: inset(0 0 0 0);
transition: clip-path 1100ms cubic-bezier(0.16, 1, 0.3, 1);
}
html.js .slot img { transform: scale(1.12); transition: transform 1600ms cubic-bezier(0.16, 1, 0.3, 1); }
html.js .hero-line.shutter .slot img { transform: scale(1); }
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
html.js [data-rv] { opacity: 1; transform: none; transition: none; }
html.js .slot, html.js .hero-line.shutter .slot { clip-path: none; transition: none; }
html.js .slot img, html.js .hero-line.shutter .slot img { transform: none; transition: none; }
.map-figure img { transform: none !important; }
}
/* ---------- narrow screens ---------- */
@media (max-width: 900px) {
.hero-foot { grid-template-columns: 1fr; gap: 24px; }
.hero-say { grid-column: 1 / -1; }
.hero-foot .btn { grid-column: 1 / -1; justify-self: start; }
.open-copy h2,
.open-copy p,
.open-figure { grid-column: 1 / -1; }
.open-figure { width: min(100%, 24em); }
.tips-side,
.tips-list { grid-column: 1 / -1; }
.tips-note { margin-bottom: 28px; }
.about h2, .bio, .about-facts { grid-column: 1 / -1; }
.foot-invite { grid-column: 1 / -1; }
.foot-top .btn { grid-column: 1 / -1; justify-self: start; margin-top: 28px; }
.foot { min-height: auto; }
}
@media (max-width: 700px) {
.hero-line {
flex-direction: column;
align-items: flex-start;
gap: 14px;
font-size: clamp(26px, 7.6vw, 34px);
line-height: 1.04;
}
.slot {
width: 1.7em;
height: 0.7em;
vertical-align: 0;
}
.about {
grid-template-areas:
"head head head head head head head head head head head head"
"bio bio bio bio bio bio bio bio bio bio bio bio"
"facts facts facts facts facts facts facts facts facts facts facts facts";
gap: 0;
}
.about-facts { flex-direction: row; flex-wrap: wrap; gap: 6px 18px; margin: 28px 0 0; }
}
@media (max-width: 620px) {
.topbar { padding-top: 18px; }
.nav { gap: 14px; font-size: 13px; }
.nav a:not(.nav-action):not(:first-child) { display: none; }
.hero { padding-top: 96px; }
.hero-line { line-height: 0.98; }
.slot { width: 1.5em; height: 0.6em; }
.statement { font-size: 22px; line-height: 1.25; }
.statement .thumb:nth-of-type(2) { display: none; }
.band-switch { min-height: 132px; gap: 16px; }
.band-text { line-height: 1.06; }
.tips h2 { margin-bottom: 56px; }
.tips-list li { grid-template-columns: 1fr auto; padding-bottom: 22px; }
.tip-kind { grid-column: 1; }
.tip-what { grid-column: 1 / -1; }
.tip-where { grid-column: 1 / -1; }
.dropcap { width: 3.2em; height: 3.2em; }
.bio { font-size: 22px; line-height: 1.28; }
.ask-line { font-size: var(--t-statement); }
.ask-line label { flex: 1 1 100%; }
.ask-line input { flex: 1 1 100%; order: 3; height: 2.4em; font-size: 0.8em; }
.ask-send { order: 4; height: 2em; font-size: 0.8em; }
.foot-name { font-size: 26vw; }
}