Styling changes, avoid glitches even on very small screens.

This commit is contained in:
Leo Vasanko
2025-09-25 07:19:40 -06:00
parent d461a42ae5
commit 0859e77b6a
9 changed files with 46 additions and 64 deletions

View File

@@ -7,7 +7,9 @@
* {
box-sizing: border-box;
}
html {
font-size: min(3vmin, 16px);
}
html,
body {
height: 100%;
@@ -16,7 +18,7 @@ body {
body {
margin: 0;
font:
500 14px/1.2 ui-sans-serif,
500 1rem/1.2 ui-sans-serif,
system-ui,
-apple-system,
Segoe UI,

View File

@@ -206,7 +206,7 @@ onUnmounted(() => {
</div>
</template>
<style scoped>
<style>
.ec-modal {
position: fixed; /* still fixed for overlay & dragging, but now top/left are set dynamically */
background: color-mix(in srgb, var(--panel) 85%, transparent);

View File

@@ -9,14 +9,12 @@ const props = defineProps({
// Reactive viewport width detection
const isNarrowView = ref(false)
const isVeryNarrowView = ref(false)
const isSmallView = ref(false)
function checkViewportWidth() {
const width = window.innerWidth
isSmallView.value = width < 800
isNarrowView.value = width < 600
isVeryNarrowView.value = width < 400
}
onMounted(() => {
@@ -30,27 +28,12 @@ onBeforeUnmount(() => {
const formattedDate = computed(() => {
const date = fromLocalString(props.day.date)
let options = { day: 'numeric', month: 'short' }
if (isVeryNarrowView.value) {
// Very narrow: show only day number
options = { day: 'numeric' }
} else if (isNarrowView.value) {
// Narrow: show day and month, no weekday
options = { day: 'numeric', month: 'short' }
} else {
// Wide: show weekday, day, and month
options = { weekday: 'short', day: 'numeric', month: 'short' }
}
let options = { weekday: 'short', day: 'numeric', month: 'short' }
// Remove weekday on very small viewports
if (isNarrowView.value) options = { day: 'numeric', month: 'short' }
let formatted = date.toLocaleDateString(undefined, options)
// Below 700px, replace first space with newline to force weekday on separate line
if (isSmallView.value && !isNarrowView.value && !isVeryNarrowView.value) {
formatted = formatted.replace(/\s/, '\n')
}
// Split between weekday and day/month on small viewports
if (isSmallView.value) formatted = formatted.replace(/\s/, '\n')
// Replace the last space (between month and day) with nbsp to prevent breaking there
// but keep the space after weekday (if present) as regular space to allow wrapping
formatted = formatted.replace(/\s+(?=\S+$)/, '\u00A0')
@@ -167,10 +150,9 @@ const formattedDate = computed(() => {
.lunar-phase {
grid-area: lunar-phase;
position: absolute;
inset-block-start: 0.5em;
inset-inline-end: 0.2em;
font-size: 0.8em;
opacity: 0.7;
inset-block-start: 0.1em;
inset-inline-end: 0.1em;
font-size: 0.8rem;
}
.compact-date {
@@ -178,7 +160,8 @@ const formattedDate = computed(() => {
top: 0.25em;
left: 0.25em;
inset-inline-end: 1rem; /* Space for lunar phase */
font-weight: 400;
font-weight: 300;
font-size: 0.8rem;
color: var(--ink);
line-height: 1;
pointer-events: none;
@@ -204,7 +187,7 @@ const formattedDate = computed(() => {
overflow: hidden;
max-width: 100%;
color: var(--holiday);
font-size: 1em;
font-size: 0.8em;
font-weight: 400;
line-height: 1.0;
padding-inline: 0.15em;

View File

@@ -119,7 +119,7 @@ const weekdayNames = computed(() => {
.calendar-header {
display: grid;
grid-template-columns: var(--week-w) repeat(7, 1fr) var(--month-w);
border-bottom: 2px solid var(--muted);
border-bottom: .1rem solid var(--muted);
align-items: last baseline;
flex-shrink: 0;
width: 100%;

View File

@@ -6,7 +6,6 @@ import WeekdaySelector from './WeekdaySelector.vue'
import Numeric from './Numeric.vue'
import {
addDaysStr,
getMondayOfISOWeek,
fromLocalString,
formatDateShort,
formatDateLong,
@@ -683,7 +682,7 @@ const recurrenceSummary = computed(() => {
.ec-field input[type='time'],
.ec-field input[type='number'],
.ec-field select {
border: 1px solid var(--muted);
border: .1rem solid var(--muted);
border-radius: 0.4rem;
padding: 0.5rem 0.6rem;
width: 100%;
@@ -853,7 +852,7 @@ const recurrenceSummary = computed(() => {
.freq-select {
padding: 0.4rem 0.55rem;
font-size: 0.75rem;
border: 1px solid var(--input-border);
border: .1rem solid var(--input-border);
background: var(--panel-alt);
color: var(--ink);
border-radius: 0.45rem;
@@ -867,15 +866,15 @@ const recurrenceSummary = computed(() => {
background: var(--panel-accent);
color: var(--ink);
box-shadow:
0 0 0 1px var(--input-focus),
0 0 0 4px rgba(37, 99, 235, 0.15);
0 0 0 .1rem var(--input-focus),
0 0 0 .4rem rgba(37, 99, 235, 0.15);
}
.interval-input,
.occ-input {
display: none;
}
.ec-field input[type='text'] {
border: 1px solid var(--input-border);
border: .1rem solid var(--input-border);
background: var(--panel-alt);
border-radius: 0.45rem;
padding: 0.4rem 0.5rem;
@@ -889,8 +888,8 @@ const recurrenceSummary = computed(() => {
border-color: var(--input-focus);
background: var(--panel-accent);
box-shadow:
0 0 0 1px var(--input-focus),
0 0 0 4px rgba(37, 99, 235, 0.15);
0 0 0 .1rem var(--input-focus),
0 0 0 .4rem rgba(37, 99, 235, 0.15);
}
.hint {
font-size: 0.65rem;
@@ -908,7 +907,7 @@ const recurrenceSummary = computed(() => {
align-items: center;
width: 100%;
padding: 0.6rem 0.8rem;
border: 1px solid var(--muted);
border: .1rem solid var(--muted);
background: var(--panel);
border-radius: 0.4rem;
cursor: pointer;
@@ -931,7 +930,7 @@ const recurrenceSummary = computed(() => {
display: grid;
gap: 0.6rem;
padding: 0.6rem;
border: 1px solid var(--muted);
border: .1rem solid var(--muted);
border-radius: 0.4rem;
background: color-mix(in srgb, var(--muted) 20%, transparent);
}
@@ -945,7 +944,7 @@ const recurrenceSummary = computed(() => {
.ec-repeat-modes .mode-btn {
flex: 1 1 auto;
padding: 0.4rem 0.6rem;
border: 1px solid var(--muted);
border: .1rem solid var(--muted);
background: var(--panel);
border-radius: 0.4rem;
cursor: pointer;

View File

@@ -321,18 +321,16 @@ function startLocalDrag(init, evt) {
let originalWeekday = null
let originalPattern = null
if (init.mode === 'move') {
try {
originalWeekday = new Date(init.startDate + 'T00:00:00').getDay()
const baseEv = store.getEventById(init.id)
if (
baseEv &&
baseEv.recur &&
baseEv.recur.freq === 'weeks' &&
Array.isArray(baseEv.recur.weekdays)
) {
originalPattern = [...baseEv.recur.weekdays]
}
} catch {}
originalWeekday = new Date(init.startDate + 'T00:00:00').getDay()
const baseEv = store.getEventById(init.id)
if (
baseEv &&
baseEv.recur &&
baseEv.recur.freq === 'weeks' &&
Array.isArray(baseEv.recur.weekdays)
) {
originalPattern = [...baseEv.recur.weekdays]
}
}
dragState.value = {
@@ -565,7 +563,7 @@ function applyRangeDuringDrag(st, startDate, endDate) {
inset: 0;
display: grid;
grid-template-columns: repeat(7, 1fr);
margin-top: 1.8em;
margin-top: 1.0rem;
pointer-events: none;
}
.segment-grid {

View File

@@ -272,13 +272,13 @@ onBeforeUnmount(() => {
.header-controls-leave-to {
opacity: 0;
max-height: 0;
transform: translateY(-20px);
transform: translateY(-1rem);
}
.header-controls-enter-to,
.header-controls-leave-from {
opacity: 1;
max-height: 100px;
max-height: 4rem;
transform: translateY(0);
}

View File

@@ -487,7 +487,7 @@ function parseGoToDateCandidate(input, refStr) {
padding: 0.32rem 0.5rem;
padding-inline-start: 2.05rem; /* increased space for icon */
border-radius: 0.45rem;
border: 1px solid color-mix(in srgb, var(--muted) 35%, transparent);
border: .1rem solid color-mix(in srgb, var(--muted) 35%, transparent);
background: color-mix(in srgb, var(--panel) 88%, transparent);
font: inherit;
line-height: 1.1;
@@ -532,7 +532,7 @@ function parseGoToDateCandidate(input, refStr) {
background: color-mix(in srgb, var(--panel) 85%, transparent);
padding: 0.15rem 0.3rem;
border-radius: 0.25rem;
border: 1px solid color-mix(in srgb, var(--muted) 25%, transparent);
border: .1rem solid color-mix(in srgb, var(--muted) 25%, transparent);
}
.search-bar input:focus + .shortcut-hint,
@@ -551,7 +551,7 @@ function parseGoToDateCandidate(input, refStr) {
background: color-mix(in srgb, var(--panel) 92%, transparent);
backdrop-filter: blur(0.6em);
-webkit-backdrop-filter: blur(0.6em);
border: 1px solid color-mix(in srgb, var(--muted) 35%, transparent);
border: .1rem solid color-mix(in srgb, var(--muted) 35%, transparent);
border-radius: 0.55rem;
max-height: 16rem;
overflow: auto;
@@ -593,7 +593,7 @@ function parseGoToDateCandidate(input, refStr) {
background: color-mix(in srgb, var(--panel) 92%, transparent);
backdrop-filter: blur(0.6em);
-webkit-backdrop-filter: blur(0.6em);
border: 1px solid color-mix(in srgb, var(--muted) 35%, transparent);
border: .1rem solid color-mix(in srgb, var(--muted) 35%, transparent);
border-radius: 0.55rem;
box-shadow: 0 0.5em 1.25em rgba(0, 0, 0, 0.3);
font-size: 0.7rem;

View File

@@ -253,7 +253,7 @@ defineExpose({ open })
border-inline-start: 2px solid var(--border-color);
}
select {
border: 1px solid var(--muted);
border: .1rem solid var(--muted);
background: var(--panel-alt, transparent);
color: var(--ink);
padding: 0.4rem 0.5rem;
@@ -291,7 +291,7 @@ select {
gap: 0.5rem;
}
.ec-btn {
border: 1px solid var(--muted);
border: .1rem solid var(--muted);
background: transparent;
color: var(--ink);
padding: 0.5rem 0.8rem;