diff --git a/app/assets/stylesheets/_global.css b/app/assets/stylesheets/_global.css index 6861d229e..c7e4cedd0 100644 --- a/app/assets/stylesheets/_global.css +++ b/app/assets/stylesheets/_global.css @@ -31,6 +31,11 @@ /* Components */ --btn-size: 2.65em; --footer-height: 3.5rem; + --tray-size: clamp(12rem, 25dvw, 24rem); + + @media (max-width: 799px) { + --tray-size: var(--footer-height); + } /* Z-index */ --z-events-column-header: 1; @@ -278,6 +283,7 @@ --lch-pink-lighter: 30% 0.03 346; --lch-pink-lightest: 25% 0.011 348; + --color-terminal-bg: var(--color-black); --color-terminal-text-light: oklch(var(--lch-green-dark)); --shadow: 0 0 0 1px oklch(var(--lch-black) / 0.42), diff --git a/app/assets/stylesheets/terminals.css b/app/assets/stylesheets/terminals.css index f5a97bf0a..e0902fd49 100644 --- a/app/assets/stylesheets/terminals.css +++ b/app/assets/stylesheets/terminals.css @@ -12,7 +12,6 @@ z-index: var(--z-terminal); @media (prefers-color-scheme: dark) { - background-color: var(--color-black); border-block-start: 1px solid var(--color-ink-lighter); } } diff --git a/app/assets/stylesheets/trays.css b/app/assets/stylesheets/trays.css index 07f7e6f2d..71ff46a94 100644 --- a/app/assets/stylesheets/trays.css +++ b/app/assets/stylesheets/trays.css @@ -1,21 +1,17 @@ -:root { - --tray-size: max(20dvw, 18rem); -} - @layer components { /* Container /* ------------------------------------------------------------------------ */ .tray { --tray-duration: 350ms; - --tray-margin: var(--inline-space); + --tray-margin: 0.5rem; --tray-radius: 0.25rem; --tray-timing-function: cubic-bezier(0.25, 1.25, 0.5, 1); align-items: end; - block-size: calc(var(--footer-height) - var(--tray-margin) * 2); + block-size: var(--footer-height); display: grid; - inset-block: auto var(--tray-margin); + inset-block: auto 0; inline-size: var(--tray-size); position: fixed; z-index: var(--z-tray); @@ -25,6 +21,15 @@ grid-column-start: 1; grid-row-start: 1; } + + @media (max-width: 799px) { + &:has(.tray__dialog[open]) { + background-color: var(--color-terminal-bg); + inline-size: calc(100% - var(--tray-margin) * 2); + inset-inline-start: var(--tray-margin); + z-index: calc(var(--z-tray) + 2); + } + } } /* Dialog @@ -40,22 +45,22 @@ transition: var(--tray-duration) var(--tray-timing-function); transition-property: background-color, box-shadow, inset-block-end; - &:not([open]) { - block-size: var(--footer-height); - pointer-events: none; - } - &[open] { border-radius: var(--tray-radius); box-shadow: 0 0 0 1px var(--color-ink-lighter), 0 0 16px oklch(var(--lch-black) / 33%); - inset-block-end: calc(var(--footer-height) - var(--tray-margin)); + inset-block-end: var(--footer-height); overflow: hidden; } + + &:not([open]) { + block-size: var(--footer-height); + pointer-events: none; + } } - /* Expander & Actions + /* Expander /* ------------------------------------------------------------------------ */ .tray__expander { @@ -65,15 +70,50 @@ align-self: stretch; background: transparent; border: 0; - margin-block: calc(-1 * var(--tray-margin)); + display: grid; + place-content: center; z-index: calc(var(--z-tray) + 1); - .tray__dialog[open] ~ &, - .tray__dialog:not(:has(.tray__item:not(.tray__item--overflow))) ~ & { + .icon { + color: var(--color-white); display: none; } + + .tray__dialog[open] ~ & { + display: none; + } + + /* On mobile, add an icon to the expander button */ + @media (max-width: 799px) { + inline-size: var(--footer-height); + + .icon { + display: block; + } + + /* Show a red dot if there are items to show */ + .tray__dialog:has(.tray__item:not(.tray__item--overflow)) ~ &:after { + background: oklch(var(--lch-red-medium)); + block-size: 1ch; + border-radius: 50%; + content: ""; + inline-size: 1ch; + inset: 25% 25% auto auto; + position: absolute; + } + } + + /* On desktop, hide if there aren't any items to show */ + @media (min-width: 800px) { + .tray__dialog:not(:has(.tray__item:not(.tray__item--overflow))) ~ & { + display: none + } + } } + /* Actions + /* ------------------------------------------------------------------------ */ + .tray__actions { --hover-size: 0; @@ -88,12 +128,6 @@ transition: translate var(--tray-duration) var(--tray-timing-function); translate: 0 var(--footer-height); - .tray__dialog[open] ~ &, - .tray__dialog:not(:has(.tray__item:not(.tray__item--overflow))) ~ & { - opacity: 1; - translate: 0 0; - } - /* Get the circle buttons to be full-height without magic numbers */ form { aspect-ratio: 1; @@ -113,6 +147,19 @@ } } + .tray__dialog[open] ~ & { + opacity: 1; + translate: 0 0; + } + + /* On desktop, show actions when there aren't items */ + @media (min-width: 800px) { + .tray__dialog:not(:has(.tray__item:not(.tray__item--overflow))) ~ & { + opacity: 1; + translate: 0 0; + } + } + @media (prefers-color-scheme: dark) { .btn--reversed { color: var(--color-ink); @@ -136,14 +183,18 @@ .tray__dialog & { font-size: 10px; + margin-block-end: var(--tray-item-margin); transition: var(--tray-duration) var(--tray-timing-function); transition-delay: var(--tray-item-delay); transition-property: margin, scale; z-index: var(--tray-item-z); + &:first-child { + --tray-item-margin: var(--tray-margin); + } + &:not(:first-child) { scale: var(--tray-item-scale); - margin-block-end: var(--tray-item-margin); } &:nth-child(1) { --tray-item-index: 1; } @@ -163,6 +214,12 @@ --tray-item-scale: 1; } + .tray__dialog:not([open]) & { + @media (max-width: 799px) { + opacity: 0; + } + } + .bubble { display: none; } @@ -183,6 +240,7 @@ justify-content: center; } + /* Only show when there are 7+ items */ .tray__dialog:has(.tray__item:nth-child(7)) & { display: flex; } @@ -238,21 +296,12 @@ } } - /* Pins tray + /* Pin-specific styles /* ------------------------------------------------------------------------ */ .tray--pins { inset-inline: var(--tray-margin) auto; - /* Don't expand if there's only one pin */ - .tray__dialog:has(.tray__item:only-child) { - pointer-events: unset; - - ~ .tray__expander { - display: none; - } - } - .tray__item { --tray-item-z: calc(10 - var(--tray-item-index)); @@ -308,9 +357,38 @@ .card__bubble { display: none; } + + /* On mobile… */ + @media (max-width: 799px) { + /* …add a border */ + .tray__expander { + border-inline-end: 1px dashed oklch(var(--lch-white) / 50%); + translate: calc(-1 * var(--tray-margin)) 0; + } + + /* …and disable the expander if there aren't items to show */ + .tray__dialog:not(:has(.tray__item:not(.tray__item--overflow))) ~ .tray__expander { + pointer-events: none; + + .icon { + opacity: 0.5; + } + } + } + + /* On desktop, don't expand if there's only one pin */ + @media (min-width: 800px) { + .tray__dialog:has(.tray__item:only-child) { + pointer-events: unset; + + ~ .tray__expander { + display: none; + } + } + } } - /* Notifications tray + /* Notification-specific styles /* ------------------------------------------------------------------------ */ .tray--notifications { @@ -334,5 +412,19 @@ .card__notification-meta { font-size: var(--text-x-small); } + + /* On mobile… */ + @media (max-width: 799px) { + /* …add a border */ + .tray__expander { + border-inline-start: 1px dashed oklch(var(--lch-white) / 50%); + translate: var(--tray-margin) 0; + } + + /* …and hide the dialog if there aren't items to show */ + .tray__dialog:not(:has(.tray__item:not(.tray__item--overflow))) { + display: none; + } + } } } diff --git a/app/views/my/pins/_tray.html.erb b/app/views/my/pins/_tray.html.erb index 955f34003..615b61e96 100644 --- a/app/views/my/pins/_tray.html.erb +++ b/app/views/my/pins/_tray.html.erb @@ -12,5 +12,7 @@ - + diff --git a/app/views/notifications/_tray.html.erb b/app/views/notifications/_tray.html.erb index 03faacab3..ad5275251 100644 --- a/app/views/notifications/_tray.html.erb +++ b/app/views/notifications/_tray.html.erb @@ -23,6 +23,7 @@ <%= link_to tag.span("Notifications"), notifications_path, class: "btn btn--reversed borderless fill-transparent center txt-uppercase txt-x-small full-width", + title: "See all notifications", data: { action: "click->dialog#close" } %> <%= link_to settings_notifications_path, @@ -33,5 +34,7 @@ <% end %> - +