Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions app/assets/stylesheets/css/components/breadcrumbs.css
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
.breadcrumbs {
@apply sticky z-40 w-full bg-(--color-main-content-background) mb-4;
/* top: calc(var(--top-navbar-height) + var(--spacing) * 4); */
top: calc(var(--top-navbar-height) + var(--spacing) * 2);
margin-top: --spacing(-2);

/* Fake background so the content scrolling underneath the breadcrumbs doesn't look like it's bleeding through */
&::before {
content: "";
position: absolute;
width: 100%;
top: 0;
left: 0;
right: 0;
inset-inline: 0.25rem;
height: calc(0.5rem);
transform: translateY(-100%);
background: var(--color-main-content-background);
pointer-events: none;
}
}

/* Soft fade strip just below the sticky breadcrumbs — eases the seam between
/* Soft fade strip just below the sticky breadcrumbs. Eases the seam between
the breadcrumb bar and the content scrolling underneath. */
.breadcrumbs::after {
content: "";
position: absolute;
top: auto;
bottom: 0;
left: 0;
right: 0;
inset-inline: 0.25rem;
transform: translateY(100%);
height: --spacing(4);
background: linear-gradient(
Expand Down
39 changes: 28 additions & 11 deletions app/assets/stylesheets/css/components/color_scheme_switcher.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,35 @@
@apply inline-flex items-center;
}

/* The switcher's trigger surfaces (inline pill + compact trigger) sit on the
dark top-navbar in both schemes, so they use primitive neutral tokens that
don't flip with light/dark — matching breadcrumbs and the sidebar toggle.
/* The switcher's trigger surfaces inherit the scoped top navbar palette.
The popover panels below stay theme-adaptive because they render on the
page surface, not the navbar. */

/* Inline pill three sections sit in a single rounded container */
/* Inline pill: three sections sit in a single rounded container */
.color-scheme-switcher--inline {
@apply gap-1 p-1 rounded-lg bg-avo-neutral-800 border border-avo-neutral-700;
@apply gap-1 p-1 rounded-lg border;
background-color: var(--top-navbar-control-background);
border-color: var(--top-navbar-control-border);
}

/* Compact a single icon trigger that opens a unified panel */
/* Compact: a single icon trigger that opens a unified panel */
.color-scheme-switcher--compact {
@apply gap-0;
}

.color-scheme-switcher__compact-trigger {
@apply inline-flex items-center gap-1 h-8 ps-2 pe-1.5 rounded-lg transition-all duration-150;
@apply text-avo-neutral-300 bg-avo-neutral-800 border border-avo-neutral-700 hover:bg-avo-neutral-700 hover:text-avo-neutral-50;
@apply border;
@apply focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-400 focus-visible:ring-offset-1;
@apply cursor-pointer;
background-color: var(--top-navbar-control-background);
border-color: var(--top-navbar-control-border);
color: var(--top-navbar-content);

&:hover {
background-color: var(--top-navbar-control-background-hover);
color: var(--top-navbar-content-hover);
}
}

.color-scheme-switcher__chevron {
Expand Down Expand Up @@ -126,22 +134,31 @@
}

.color-scheme-switcher__button {
@apply inline-flex items-center justify-center p-1.5 py-0.5 rounded-md transition-all duration-150 text-avo-neutral-300 hover:bg-avo-neutral-700 hover:text-avo-neutral-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-400 focus-visible:ring-offset-1 active:scale-95;
@apply inline-flex items-center justify-center p-1.5 py-0.5 rounded-md transition-all duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-400 focus-visible:ring-offset-1 active:scale-95;
@apply border-0 bg-transparent cursor-pointer;
color: var(--top-navbar-content);

&:hover {
background-color: var(--top-navbar-control-background-hover);
color: var(--top-navbar-content-hover);
}
}

/* Scheme buttons - idle vs active state. The active "pill" stands out against
the neutral-800 inline pill background by going darker (neutral-950). */
the inline pill background through the scoped navbar active tokens. */
.color-scheme-switcher__button[data-scheme="light"],
.color-scheme-switcher__button[data-scheme="dark"],
.color-scheme-switcher__button[data-scheme="auto"] {
@apply bg-transparent text-avo-neutral-300 shadow-none;
@apply bg-transparent shadow-none;
color: var(--top-navbar-content);
}

.scheme-light .color-scheme-switcher__button[data-scheme="light"],
.scheme-dark .color-scheme-switcher__button[data-scheme="dark"],
.scheme-auto .color-scheme-switcher__button[data-scheme="auto"] {
@apply bg-avo-neutral-950 text-avo-neutral-50 shadow-sm;
@apply shadow-sm;
background-color: var(--top-navbar-active-background);
color: var(--top-navbar-active-content);
}

.color-scheme-switcher__icon {
Expand Down
122 changes: 88 additions & 34 deletions app/assets/stylesheets/css/layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
the top-navbar and .main (which are siblings, not parent/child).
--content-width is intentionally relative to .main's content box (which is
already offset by --sidebar-offset-size via padding), so centering via
mx-auto happens inside the area to the right of the sidebar not the page. */
mx-auto happens inside the area to the right of the sidebar, not the page. */
[data-controller~="sidebar"] {
--sidebar-width: --spacing(64);
--sidebar-offset-size: 0rem;
Expand All @@ -64,12 +64,29 @@
}

.main-content {
@apply w-(--content-width) flex flex-col bg-(--color-main-content-background) py-2 lg:py-4 px-2 lg:px-4 border-s border-(--color-main-content-border) ms-1 rounded-se-(--navbar-notch-radius) rounded-ss-(--navbar-notch-radius);
--main-content-start-radius: 0px;
--main-content-end-radius: 0px;

@apply relative w-(--content-width) flex flex-col bg-(--color-main-content-background) py-2 lg:py-4 px-2 lg:px-4 border-s border-(--color-main-content-border) ms-1 rounded-se-(--main-content-end-radius) rounded-ss-(--main-content-start-radius);

transition: margin 0.1s ease-in-out, width 0.1s ease-in-out;
min-height: calc(100dvh - var(--top-navbar-height) - var(--spacing));

@container style(--navbar-notch-enabled: true) {
--main-content-end-radius: var(--main-content-radius);
}

@container style(--navbar-notch-enabled: true) and style(--top-navbar-start-notch-align-with-main-content: true) {
--main-content-start-radius: var(--main-content-radius);
}
Comment thread
cursor[bot] marked this conversation as resolved.

}

.main-content.focused,
.main-content:focus-visible {
outline: 2px solid var(--color-content);
outline-offset: 2px;
}

.main-content__container {
@apply flex flex-1 flex-col px-2;
Expand All @@ -90,6 +107,45 @@
.top-navbar {
@apply z-100 fixed top-0 inset-x-0 w-full shrink-0 pointer-events-none;

/* Top navbar theme contract.
Override these variables on `.top-navbar` when the navbar needs its own
palette. They are defined here so the customization point stays local to
the navbar while popovers, dropdown panels, and the main content keep using
their own surface tokens.

Example:
.top-navbar {
--top-navbar-background: var(--color-primary);
--top-navbar-content: var(--color-content-secondary);
--top-navbar-content-hover: var(--color-content);
--top-navbar-control-background: var(--color-secondary);
--top-navbar-control-background-hover: var(--color-tertiary);
--top-navbar-control-border: var(--color-tertiary);
--top-navbar-control-content: var(--color-content);
--top-navbar-control-muted: var(--color-content-secondary);
--top-navbar-control-shortcut-background: var(--color-primary);
--top-navbar-control-shortcut-border: var(--color-tertiary);
--top-navbar-control-shortcut-content: var(--color-content-secondary);
--top-navbar-active-background: var(--color-foreground);
--top-navbar-active-content: var(--color-background);
}
*/
--top-navbar-background: var(--color-navbar-background);
--top-navbar-content: var(--color-avo-neutral-300);
--top-navbar-content-hover: var(--color-avo-neutral-50);
--top-navbar-control-background: var(--color-avo-neutral-800);
--top-navbar-control-background-hover: var(--color-avo-neutral-700);
--top-navbar-control-border: var(--color-avo-neutral-700);
--top-navbar-control-content: var(--color-avo-neutral-50);
--top-navbar-control-muted: var(--color-avo-neutral-400);
--top-navbar-control-shortcut-background: var(--color-avo-neutral-700);
--top-navbar-control-shortcut-border: var(--color-avo-neutral-600);
--top-navbar-control-shortcut-content: var(--color-avo-neutral-200);
--top-navbar-active-background: var(--color-avo-neutral-950);
--top-navbar-active-content: var(--color-avo-neutral-50);
--top-navbar-start-notch-offset: 0px;
--navbar-notch-color: var(--top-navbar-background);

/* Three-region grid: start | center | end. start/end share remaining space
equally (1fr each) so the center column (search) stays visually anchored
to the navbar's midpoint regardless of breadcrumb length. */
Expand All @@ -99,7 +155,7 @@
gap: 0.75rem;
padding-inline: 0.5rem;

background-color: var(--color-navbar-background);
background-color: var(--top-navbar-background);

> * {
@apply pointer-events-auto;
Expand All @@ -109,7 +165,7 @@
@apply flex-nowrap overflow-x-auto;
}

/* Inverted arches at the top corners of the content area a square just
/* Inverted arches at the top corners of the content area: a square just
below the navbar painted with the notch color, with a quarter-circle cut
out of one bottom corner. The cut reveals the content beneath, so the
content looks like it has a rounded top corner without actually applying
Expand All @@ -136,8 +192,17 @@
}
}

/* Moves the start notch to the main content start edge when requested. This
produces a different rounded look for layouts where the navbar should read
as one continuous strip above the sidebar and content panel. */
@container style(--top-navbar-start-notch-align-with-main-content: true) {
&::before {
--top-navbar-start-notch-offset: var(--sidebar-offset-size);
}
}

&::before {
left: 0;
inset-inline-start: var(--top-navbar-start-notch-offset);
background: radial-gradient(
circle var(--navbar-notch-radius) at 100% 100%,
transparent 99%,
Expand All @@ -146,7 +211,7 @@
}

&::after {
right: 0;
inset-inline-end: 0;
background: radial-gradient(
circle var(--navbar-notch-radius) at 0% 100%,
transparent 99%,
Expand All @@ -168,32 +233,29 @@
.top-navbar__center {
@apply flex items-center justify-center min-w-0 sm:w-80 lg:w-96 xl:w-120;

/* Search input is rendered against the dark navbar in both light/dark
themes, so it uses primitive neutral tokens that are stable across modes
— matching the breadcrumbs and sidebar-toggle treatment. */
.search-input__input {
background-color: var(--color-avo-neutral-800);
border-color: var(--color-avo-neutral-700);
color: var(--color-avo-neutral-50);
background-color: var(--top-navbar-control-background);
border-color: var(--top-navbar-control-border);
color: var(--top-navbar-control-content);

&::placeholder {
color: var(--color-avo-neutral-400);
color: var(--top-navbar-control-muted);
}
}

.search-input__prefix,
.search-input__suffix {
color: var(--color-avo-neutral-400);
color: var(--top-navbar-control-muted);
}

.search-input__suffix kbd {
background-color: var(--color-avo-neutral-700);
border-color: var(--color-avo-neutral-600);
color: var(--color-avo-neutral-200);
background-color: var(--top-navbar-control-shortcut-background);
border-color: var(--top-navbar-control-shortcut-border);
color: var(--top-navbar-control-shortcut-content);
box-shadow: none;
}

/* On mobile, collapse the navbar search to just the input + search icon
/* On mobile, collapse the navbar search to just the input + search icon:
hide the keyboard shortcut suffix and drop the reserved end-padding so it
stays compact next to the logo. */
@media (width < theme(--breakpoint-sm)) {
Expand All @@ -215,14 +277,11 @@
@apply flex items-center justify-end gap-3 min-w-0 h-full;
}

/* Links inside the always-dark navbar use primitive neutral tokens so they
stay readable in both light and dark mode — matching the search input and
sidebar toggle treatment. */
.top-navbar .header-menu a {
color: var(--color-avo-neutral-300);
color: var(--top-navbar-content);

&:hover {
color: var(--color-avo-neutral-50);
color: var(--top-navbar-content-hover);
}
}

Expand All @@ -243,23 +302,23 @@ button[data-sidebar-state="closed"] .sidebar-toggle-icon--closed {
@apply inline-flex;
}

/* The toggle sits on the dark top-navbar, so it uses primitive neutral tokens
that are stable across light/dark — matching the breadcrumbs treatment. */
button[data-sidebar-toggle-icon] {
--btn-text-color: var(--color-avo-neutral-300);
--btn-text-color: var(--top-navbar-content);

&:hover {
--btn-text-color: var(--color-avo-neutral-50);
background-color: var(--color-avo-neutral-800);
--btn-text-color: var(--top-navbar-content-hover);
background-color: var(--top-navbar-control-background);
}
}

/* Default hidden state - LTR: sidebar slides in from left.
Sidebar starts below the navbar (matching .main's padding-top), so the
navbar is uninterrupted across the full viewport width. */
.avo-sidebar {
@apply fixed z-50 start-0 flex-1 border-e border-tertiary lg:border-none bg-sidebar-background w-(--sidebar-width);
@apply fixed z-50 start-0 flex-1 border-e lg:border-none w-(--sidebar-width);

background-color: var(--sidebar-background);
border-color: var(--sidebar-border);
top: var(--top-navbar-height);
height: calc(100dvh - var(--top-navbar-height));
transform: translateX(-100%);
Expand All @@ -281,11 +340,6 @@ html[dir="rtl"] .avo-sidebar {
html[dir="rtl"] .sidebar-open .avo-sidebar {
transform: translateX(0);
}

.sidebar-open .main-content {
Comment thread
cursor[bot] marked this conversation as resolved.
@apply rounded-ss-none;
}

.main:not(.sidebar-open) .main-content {
@apply ms-0;
}
Expand Down
Loading
Loading