diff --git a/country-explorer/src/components/App.css b/country-explorer/src/components/App.css index c1321cc..42e6729 100644 --- a/country-explorer/src/components/App.css +++ b/country-explorer/src/components/App.css @@ -1 +1,64 @@ -/* Main layout styles go here. */ +header { + padding: 0 0 var(--space-3); + max-width: 700px; +} +header::before { + content: ''; + display: block; + width: 2.75rem; + height: 0.3rem; + border-radius: 1rem; + background: var(--accent); + margin-bottom: var(--space-3); +} +header p { + max-width: 540px; + font-size: 1.1rem; +} +main { + display: grid; + gap: var(--space-3); +} +main > section { + min-width: 0; + padding: clamp(1.25rem, 3vw, 2rem); + background: var(--bg); + border: 1px solid var(--border); + border-radius: 1.25rem; + box-shadow: 0 4px 20px #183c3204; +} +section[aria-labelledby='controls-heading'] { + display: grid; + grid-template-columns: 1fr 1fr 1.4fr; + gap: var(--space-3); +} +#controls-heading { + grid-column: 1 / -1; + margin: 0; +} +section > [role='status'] { + padding: var(--space-3); + border: 1px dashed #b8cabe; + border-radius: 0.75rem; + background: #f8faf7; +} +[role='alert'] { + padding: var(--space-3); + border: 1px solid #e0b6ae; + border-radius: 0.75rem; + color: #883b2c; + background: #fff7f4; +} +[role='alert'] button { + margin-top: var(--space-2); +} +footer { + padding: var(--space-4) 0 var(--space-2); + text-align: center; + font-size: 0.85rem; +} +@media (max-width: 680px) { + section[aria-labelledby='controls-heading'] { + grid-template-columns: 1fr; + } +} diff --git a/country-explorer/src/components/CountryCard.css b/country-explorer/src/components/CountryCard.css index c20369c..78c2031 100644 --- a/country-explorer/src/components/CountryCard.css +++ b/country-explorer/src/components/CountryCard.css @@ -1,61 +1,78 @@ .country-card { - display: flex; - flex-wrap: wrap; - gap: 1.5rem; - margin: 1rem; - padding: clamp(1rem, 3vw, 2rem); - border: 1px solid var(--border); - border-radius: 12px; - background: var(--bg); + display: grid; + grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.4fr); + align-items: start; + gap: clamp(1.5rem, 4vw, 3rem); + padding-block: var(--space-1) var(--space-3); text-align: left; } - .country-card__flag, .country-card__flag-placeholder { width: 100%; - max-width: 16rem; - align-self: flex-start; + border: 1px solid var(--border); + border-radius: 0.75rem; } - .country-card__flag { + display: block; height: auto; - object-fit: contain; } - +.country-card__flag-placeholder { + aspect-ratio: 3 / 2; + background: #f4f6f3; + display: grid; + place-items: center; + padding: var(--space-2); +} .country-card__content { - flex: 1 1 16rem; min-width: 0; overflow-wrap: anywhere; } - .country-card__heading-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; - gap: 0.75rem; - margin: 0 0 1rem; + gap: var(--space-2); + margin-bottom: var(--space-3); } - .country-card__heading-row h3 { margin: 0; - color: var(--text-h); - font-size: 1.5rem; - line-height: 1.3; + font-size: clamp(1.6rem, 3vw, 2.25rem); + letter-spacing: -0.035em; } - .country-card__details { display: grid; - gap: 1rem; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--space-3); margin: 0; } - +.country-card__details > div { + border-top: 1px solid var(--border); + padding-top: 0.75rem; +} .country-card__details dt { - color: var(--text-h); - font-weight: 600; + font-size: 0.8rem; + font-weight: 500; + color: var(--text); } - .country-card__details dd { margin: 0.25rem 0 0; + font-weight: 600; + color: var(--text-h); font-variant-numeric: tabular-nums; } +@media (max-width: 680px) { + .country-card { + grid-template-columns: 1fr; + } + .country-card__flag, + .country-card__flag-placeholder { + max-width: 22rem; + justify-self: center; + } +} +@media (max-width: 360px) { + .country-card__details { + grid-template-columns: 1fr; + } +} diff --git a/country-explorer/src/components/CountrySelector.css b/country-explorer/src/components/CountrySelector.css index 5bd5534..5b64015 100644 --- a/country-explorer/src/components/CountrySelector.css +++ b/country-explorer/src/components/CountrySelector.css @@ -1,24 +1,11 @@ .country-selection { display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: center; - gap: 0.5rem; - margin: 1rem; -} - -.country-selection select { + flex-direction: column; + gap: var(--space-1); min-width: 0; - max-width: 100%; - padding: 0.5rem; - font: inherit; - color: var(--text-h); - background: var(--bg); - border: 1px solid var(--border); - border-radius: 4px; } - -.country-selection select:focus-visible { - outline: 2px solid var(--accent); - outline-offset: 3px; +.country-selection label { + color: var(--text); + font-size: 0.8rem; + font-weight: 600; } diff --git a/country-explorer/src/components/FavoriteButton.css b/country-explorer/src/components/FavoriteButton.css index 9ffb4e7..5f28ddf 100644 --- a/country-explorer/src/components/FavoriteButton.css +++ b/country-explorer/src/components/FavoriteButton.css @@ -1,35 +1,19 @@ .favorite-button { display: inline-flex; align-items: center; - gap: 0.4rem; - flex-shrink: 0; - min-height: 44px; - padding: 0.5rem 1rem; - font: inherit; - color: var(--text-h); - background: var(--bg); - border: 1px solid var(--border); - border-radius: 4px; - cursor: pointer; + justify-content: center; + gap: var(--space-1); + font-size: 0.875rem; } - -.favorite-button:hover { - background: var(--accent-bg); - border-color: var(--accent); -} - -.favorite-button:focus-visible { - outline: 2px solid var(--accent); - outline-offset: 3px; -} - .favorite-button[aria-pressed='true'] { color: var(--accent); border-color: var(--accent); background: var(--accent-bg); } - +.favorite-button[aria-pressed='true']:hover { + background: #d9ebdf; +} .favorite-button__icon { - font-size: 1.2em; + font-size: 1.3em; line-height: 1; } diff --git a/country-explorer/src/components/FavoritesList.css b/country-explorer/src/components/FavoritesList.css index 8bbe6df..08fd5c6 100644 --- a/country-explorer/src/components/FavoritesList.css +++ b/country-explorer/src/components/FavoritesList.css @@ -1,30 +1,20 @@ .favorites-list { display: flex; flex-wrap: wrap; - justify-content: center; - gap: 0.5rem; - margin: 1rem; + gap: 0.75rem; + margin: 0; padding: 0; list-style: none; } - -.favorites-list button { - min-height: 44px; - padding: 0.5rem 1rem; - font: inherit; - color: var(--text-h); - background: var(--bg); - border: 1px solid var(--border); - border-radius: 4px; - cursor: pointer; +.favorites-list li { + min-width: 0; + max-width: 100%; } - -.favorites-list button:hover { +.favorites-list button { + border-radius: 2rem; background: var(--accent-bg); - border-color: var(--accent); -} - -.favorites-list button:focus-visible { - outline: 2px solid var(--accent); - outline-offset: 3px; + border-color: var(--border); + color: var(--accent); + overflow-wrap: anywhere; + text-align: left; } diff --git a/country-explorer/src/components/NavigationControls.css b/country-explorer/src/components/NavigationControls.css index 5bbb23b..eb24d07 100644 --- a/country-explorer/src/components/NavigationControls.css +++ b/country-explorer/src/components/NavigationControls.css @@ -1,34 +1,18 @@ .country-navigation { display: flex; flex-wrap: wrap; - justify-content: center; + justify-content: space-between; align-items: center; - gap: 1rem; - margin: 1rem; + gap: var(--space-2); + padding-top: var(--space-3); + border-top: 1px solid var(--border); + font-size: 0.875rem; } - -.country-navigation button { - min-height: 44px; - padding: 0.5rem 1rem; - font: inherit; - color: var(--text-h); - background: var(--bg); - border: 1px solid var(--border); - border-radius: 4px; - cursor: pointer; -} - -.country-navigation button:hover:not(:disabled) { - background: var(--accent-bg); +.country-navigation button:not(:disabled) { + background: var(--accent); border-color: var(--accent); + color: white; } - -.country-navigation button:focus-visible { - outline: 2px solid var(--accent); - outline-offset: 3px; -} - -.country-navigation button:disabled { - opacity: 0.5; - cursor: default; +.country-navigation button:hover:not(:disabled) { + background: #174a39; } diff --git a/country-explorer/src/components/RegionFilter.css b/country-explorer/src/components/RegionFilter.css index a3aea2f..3ae4c90 100644 --- a/country-explorer/src/components/RegionFilter.css +++ b/country-explorer/src/components/RegionFilter.css @@ -1,24 +1,11 @@ .region-filter { display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: center; - gap: 0.5rem; - margin: 1rem; -} - -.region-filter select { + flex-direction: column; + gap: var(--space-1); min-width: 0; - max-width: 100%; - padding: 0.5rem; - font: inherit; - color: var(--text-h); - background: var(--bg); - border: 1px solid var(--border); - border-radius: 4px; } - -.region-filter select:focus-visible { - outline: 2px solid var(--accent); - outline-offset: 3px; +.region-filter label { + color: var(--text); + font-size: 0.8rem; + font-weight: 600; } diff --git a/country-explorer/src/components/SortSelector.css b/country-explorer/src/components/SortSelector.css index e823c24..3d745fc 100644 --- a/country-explorer/src/components/SortSelector.css +++ b/country-explorer/src/components/SortSelector.css @@ -1,24 +1,11 @@ .sort-selector { display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: center; - gap: 0.5rem; - margin: 1rem; -} - -.sort-selector select { + flex-direction: column; + gap: var(--space-1); min-width: 0; - max-width: 100%; - padding: 0.5rem; - font: inherit; - color: var(--text-h); - background: var(--bg); - border: 1px solid var(--border); - border-radius: 4px; } - -.sort-selector select:focus-visible { - outline: 2px solid var(--accent); - outline-offset: 3px; +.sort-selector label { + color: var(--text); + font-size: 0.8rem; + font-weight: 600; } diff --git a/country-explorer/src/index.css b/country-explorer/src/index.css index 2d9d4db..27ae122 100644 --- a/country-explorer/src/index.css +++ b/country-explorer/src/index.css @@ -1,105 +1,141 @@ +/* Shared design tokens and native control styles. */ :root { - --text: #6b6375; - --text-h: #08060d; - --bg: #fff; - --border: #e5e4e7; - --code-bg: #f4f3ec; - --accent: #aa3bff; - --accent-bg: rgba(170, 59, 255, 0.1); - --accent-border: rgba(170, 59, 255, 0.5); - --social-bg: rgba(244, 243, 236, 0.5); - --shadow: rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px; - - --sans: system-ui, 'Segoe UI', Roboto, sans-serif; - --heading: system-ui, 'Segoe UI', Roboto, sans-serif; - --mono: ui-monospace, Consolas, monospace; - - font: 18px/145% var(--sans); - letter-spacing: 0.18px; - color-scheme: light dark; - color: var(--text); - background: var(--bg); + font-family: + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + sans-serif; + color: #52645f; + background: #f4f6f3; + color-scheme: light; font-synthesis: none; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - @media (max-width: 1024px) { - font-size: 16px; - } -} - -@media (prefers-color-scheme: dark) { - :root { - --text: #9ca3af; - --text-h: #f3f4f6; - --bg: #16171d; - --border: #2e303a; - --code-bg: #1f2028; - --accent: #c084fc; - --accent-bg: rgba(192, 132, 252, 0.15); - --accent-border: rgba(192, 132, 252, 0.5); - --social-bg: rgba(47, 48, 58, 0.5); - --shadow: rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px; - } + --text: #52645f; + --text-h: #183c32; + --bg: #fff; + --border: #dce5df; + --accent: #21634e; + --accent-bg: #eaf3ed; + --space-1: 0.5rem; + --space-2: 1rem; + --space-3: 1.5rem; + --space-4: 2rem; } - -#root { - width: 1126px; - max-width: 100%; - margin: 0 auto; - text-align: center; - border-inline: 1px solid var(--border); - min-height: 100svh; - display: flex; - flex-direction: column; +* { box-sizing: border-box; } - body { margin: 0; + min-width: 280px; + font-size: 1rem; + line-height: 1.6; +} +#root { + max-width: 1160px; + min-height: 100svh; + margin-inline: auto; + padding: clamp(1rem, 4vw, 3rem); + padding-top: 1rem; } - h1, -h2 { - font-family: var(--heading); - font-weight: 500; +h2, +h3 { color: var(--text-h); + line-height: 1.2; } - h1 { - font-size: 56px; - letter-spacing: -1.68px; - margin: 32px 0; - @media (max-width: 1024px) { - font-size: 36px; - margin: 20px 0; - } + font-size: clamp(2.25rem, 6vw, 4rem); + letter-spacing: -0.05em; + margin: 0 0 var(--space-2); } h2 { - font-size: 24px; - line-height: 118%; - letter-spacing: -0.24px; - margin: 0 0 8px; - @media (max-width: 1024px) { - font-size: 20px; - } + font-size: 1.125rem; + letter-spacing: -0.02em; + margin: 0 0 var(--space-3); } p { margin: 0; } - -code, -.counter { - font-family: var(--mono); - display: inline-flex; - border-radius: 4px; +a { + color: var(--accent); + text-underline-offset: 0.2em; +} +a:hover { + text-decoration-thickness: 2px; +} +button, +select { + font: inherit; color: var(--text-h); + background: var(--bg); + border: 1px solid #a9bcb1; + border-radius: 0.65rem; + min-height: 46px; + padding: 0.65rem 1rem; + max-width: 100%; + transition: + background-color 150ms ease, + border-color 150ms ease; +} +button { + cursor: pointer; + font-weight: 600; +} +select { + appearance: none; + width: 100%; + min-height: 50px; + padding: 0.75rem 2.75rem 0.75rem 1rem; + border-radius: 0.75rem; + background-color: #f8faf8; + background-image: + linear-gradient(45deg, transparent 50%, var(--accent) 50%), + linear-gradient(135deg, var(--accent) 50%, transparent 50%); + background-position: + calc(100% - 21px) center, + calc(100% - 16px) center; + background-size: 5px 5px; + background-repeat: no-repeat; + box-shadow: 0 1px 2px #183c3208; + cursor: pointer; +} +button:hover:not(:disabled), +select:hover:not(:disabled) { + border-color: var(--accent); + background-color: var(--accent-bg); +} +select:focus-visible { + border-color: var(--accent); + background-color: var(--bg); } - -code { - font-size: 15px; - line-height: 135%; - padding: 4px 8px; - background: var(--code-bg); +select option { + color: var(--text-h); + background-color: var(--bg); +} +@media (forced-colors: active) { + select { + appearance: auto; + background-image: none; + } +} +:where(button, select, a):focus-visible { + outline: 3px solid #286dcc; + outline-offset: 4px; +} +button:disabled, +select:disabled { + color: #68766e; + background: #edf0ed; + border-color: var(--border); + cursor: not-allowed; +} +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + transition: none !important; + } }