mirror of
https://github.com/cverinc/marktile.git
synced 2026-07-22 07:42:21 +00:00
feat: squircle corners
Layer continuous-curvature (squircle) corners on top of the existing border-radius on card/lane/button/panel/input surfaces via a `--corner: squircle` token and `corner-shape: var(--corner)`. corner-shape is Chromium-only as of mid-2026 (Safari/WebKit & Firefox ignore it and keep the plain border-radius arc), and it requires a non-zero radius to render — so this is pure progressive enhancement with zero visual regression. Pills (border-radius: 999px) and the full-screen 0-radius editor are deliberately left untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2bab893e80
commit
15813173ab
1 changed files with 27 additions and 21 deletions
48
styles.css
48
styles.css
|
|
@ -1,4 +1,10 @@
|
|||
/* tugtile — markdown kanban (prototype, read-only renderer) */
|
||||
/* Squircle corners: continuous-curvature corners layered on top of the existing
|
||||
border-radius. corner-shape is Chromium-only as of mid-2026 (Safari/WebKit & Firefox
|
||||
ignore it and keep the plain border-radius arc), so this is pure progressive
|
||||
enhancement with zero visual regression. corner-shape needs a non-zero radius to do
|
||||
anything and is not inherited — but the custom property is, so we route through a token. */
|
||||
:root { --corner: squircle; }
|
||||
.tugtile {
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
|
|
@ -44,7 +50,7 @@ body.is-phone .workspace-leaf-content[data-type="tugtile-board"] .view-content {
|
|||
.tugtile-brand {
|
||||
display: inline-flex; align-items: center; gap: 5px;
|
||||
color: var(--text-faint); font-weight: var(--font-normal);
|
||||
cursor: pointer; border-radius: var(--radius-s); padding: 2px 6px;
|
||||
cursor: pointer; border-radius: var(--radius-s); corner-shape: var(--corner); padding: 2px 6px;
|
||||
}
|
||||
.tugtile-brand:hover { background: var(--background-modifier-hover); color: var(--text-muted); }
|
||||
.tugtile-lock-icon { display: inline-flex; }
|
||||
|
|
@ -77,7 +83,7 @@ body.is-phone .workspace-leaf-content[data-type="tugtile-board"] .view-content {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--background-secondary);
|
||||
border-radius: var(--radius-m);
|
||||
border-radius: var(--radius-m); corner-shape: var(--corner);
|
||||
padding: 8px;
|
||||
overflow: hidden; /* Cleanly clips content into the changing lane width during collapse/expand (dragging uses a clone on body and is unaffected) */
|
||||
--tg-d1: 0.26s; /* Stage 1: lane narrows + horizontal title tucks into the chevron (collapse) / widens + title grows back (expand) */
|
||||
|
|
@ -127,7 +133,7 @@ body.is-phone .workspace-leaf-content[data-type="tugtile-board"] .view-content {
|
|||
position: relative;
|
||||
background: var(--background-primary);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: var(--radius-m);
|
||||
border-radius: var(--radius-m); corner-shape: var(--corner);
|
||||
padding: 8px;
|
||||
cursor: grab;
|
||||
}
|
||||
|
|
@ -167,7 +173,7 @@ body.is-phone .workspace-leaf-content[data-type="tugtile-board"] .view-content {
|
|||
padding: 0 0.4em;
|
||||
background: var(--interactive-accent);
|
||||
color: var(--text-on-accent);
|
||||
border-radius: var(--radius-s);
|
||||
border-radius: var(--radius-s); corner-shape: var(--corner);
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
|
@ -212,7 +218,7 @@ body.is-phone .workspace-leaf-content[data-type="tugtile-board"] .view-content {
|
|||
z-index: 9999;
|
||||
background: var(--background-primary);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: var(--radius-m);
|
||||
border-radius: var(--radius-m); corner-shape: var(--corner);
|
||||
box-shadow: var(--shadow-l);
|
||||
padding: 8px;
|
||||
user-select: none;
|
||||
|
|
@ -241,7 +247,7 @@ body.is-phone .workspace-leaf-content[data-type="tugtile-board"] .view-content {
|
|||
.tugtile__popup-w { opacity: 0.5; font-size: 0.8em; }
|
||||
.tugtile__popup-d {
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-s);
|
||||
border-radius: var(--radius-s); corner-shape: var(--corner);
|
||||
padding: 3px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
|
@ -255,7 +261,7 @@ body.is-phone .workspace-leaf-content[data-type="tugtile-board"] .view-content {
|
|||
.tugtile__popup-t {
|
||||
cursor: pointer;
|
||||
padding: 4px 16px;
|
||||
border-radius: var(--radius-s);
|
||||
border-radius: var(--radius-s); corner-shape: var(--corner);
|
||||
}
|
||||
.tugtile__popup-t:hover { background: var(--background-modifier-hover); }
|
||||
/* Tag chips at the bottom of the card (when move-tags-to-card-footer is enabled) */
|
||||
|
|
@ -305,7 +311,7 @@ body.is-phone .workspace-leaf-content[data-type="tugtile-board"] .view-content {
|
|||
text-align: left;
|
||||
background: transparent;
|
||||
border: 1px dashed var(--background-modifier-border);
|
||||
border-radius: var(--radius-m);
|
||||
border-radius: var(--radius-m); corner-shape: var(--corner);
|
||||
color: var(--text-muted);
|
||||
padding: 8px; /* Match card padding and the add-lane button (consistent 8px rhythm); left-aligned "+" lines up with the card number chip */
|
||||
cursor: pointer;
|
||||
|
|
@ -318,13 +324,13 @@ body.is-phone .workspace-leaf-content[data-type="tugtile-board"] .view-content {
|
|||
width: 100%;
|
||||
min-height: 4em;
|
||||
resize: vertical;
|
||||
border-radius: var(--radius-m);
|
||||
border-radius: var(--radius-m); corner-shape: var(--corner);
|
||||
}
|
||||
.tugtile__add-ok {
|
||||
background: var(--interactive-accent);
|
||||
color: var(--text-on-accent);
|
||||
border: none;
|
||||
border-radius: var(--radius-s);
|
||||
border-radius: var(--radius-s); corner-shape: var(--corner);
|
||||
padding: 4px 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
@ -438,7 +444,7 @@ body.is-phone .tugtile-prompt-modal { margin-top: calc(env(safe-area-inset-top)
|
|||
box-sizing: border-box; height: 40px; padding: 0 12px;
|
||||
background: var(--background-modifier-form-field);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: var(--radius-m);
|
||||
border-radius: var(--radius-m); corner-shape: var(--corner);
|
||||
overflow: hidden; /* Clip the input to the rounded box so it can never poke out of the corners */
|
||||
}
|
||||
.tugtile-prompt-field:focus-within { border-color: var(--interactive-accent); }
|
||||
|
|
@ -497,7 +503,7 @@ input.tugtile-prompt-input:active {
|
|||
-webkit-appearance: none; appearance: none;
|
||||
position: relative;
|
||||
width: 40px; height: 40px;
|
||||
border: none; border-radius: var(--radius-m);
|
||||
border: none; border-radius: var(--radius-m); corner-shape: var(--corner);
|
||||
background: transparent; color: var(--text-muted);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
@ -542,7 +548,7 @@ body.is-phone .tugtile-ed-bar { padding-top: 6px; padding-bottom: 4px; }
|
|||
}
|
||||
.tugtile-ed-find-i {
|
||||
flex: 1; min-width: 80px;
|
||||
font-size: 16px; padding: 5px 8px; border-radius: var(--radius-s); /* 16px avoids iOS focus-zoom */
|
||||
font-size: 16px; padding: 5px 8px; border-radius: var(--radius-s); corner-shape: var(--corner); /* 16px avoids iOS focus-zoom */
|
||||
}
|
||||
.tugtile-ed-find-n { flex: 0 0 auto; color: var(--text-muted); font-size: 0.85em; min-width: 1.6em; text-align: center; }
|
||||
/* .tugtile-ed-find-b inherits everything from .tugtile-iconbtn */
|
||||
|
|
@ -609,7 +615,7 @@ body.is-phone .tugtile-ed-bar { padding-top: 6px; padding-bottom: 4px; }
|
|||
.marktile-toc-item--ghost { opacity: 0.4; background: var(--background-modifier-hover); } /* the gap left behind */
|
||||
.marktile-toc-item--chosen { box-shadow: inset 0 0 0 2px var(--interactive-accent); } /* the picked row */
|
||||
.marktile-toc-item--drag { /* the row following the finger (re-parented to <body> by fallbackOnBody) */
|
||||
opacity: 0.97; background: var(--background-secondary); border-radius: 6px;
|
||||
opacity: 0.97; background: var(--background-secondary); border-radius: 6px; corner-shape: var(--corner);
|
||||
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.4); cursor: grabbing;
|
||||
rotate: 3deg; scale: 1.03; /* "picked up" tilt — standalone props (NOT transform) so Sortable's drag translation isn't overwritten */
|
||||
}
|
||||
|
|
@ -658,7 +664,7 @@ body.is-phone .tugtile-ed-rich { padding-bottom: 55vh; }
|
|||
width: 100%;
|
||||
min-height: 4em;
|
||||
resize: vertical;
|
||||
border-radius: var(--radius-s);
|
||||
border-radius: var(--radius-s); corner-shape: var(--corner);
|
||||
}
|
||||
/* Lane header container */
|
||||
.tugtile__lane-title {
|
||||
|
|
@ -679,7 +685,7 @@ body.is-phone .tugtile-ed-rich { padding-bottom: 55vh; }
|
|||
.tugtile__lane-rename {
|
||||
flex: 1;
|
||||
font-weight: 700;
|
||||
border-radius: var(--radius-s);
|
||||
border-radius: var(--radius-s); corner-shape: var(--corner);
|
||||
}
|
||||
/* Responsive board (opt-in, default off): on a narrow pane the horizontal lanes reflow into a single full-width vertical stack — the behaviour of the retired List view, now automatic via a container query. Drag-and-drop/editing logic is shared with the board view. */
|
||||
.tugtile--rwd { container-type: inline-size; container-name: tugtileboard; }
|
||||
|
|
@ -698,7 +704,7 @@ body.is-phone .tugtile-ed-rich { padding-bottom: 55vh; }
|
|||
/* Centered header view-cycle control: "<icon> <name>" — click cycles board → table → markdown. Same padding as the lock button so the "·" separator sits symmetrically between them. */
|
||||
.tugtile-viewcycle {
|
||||
display: inline-flex; align-items: center; gap: 5px;
|
||||
cursor: pointer; border-radius: var(--radius-s);
|
||||
cursor: pointer; border-radius: var(--radius-s); corner-shape: var(--corner);
|
||||
padding: 2px 6px;
|
||||
}
|
||||
.tugtile-viewcycle:hover { background: var(--background-modifier-hover); }
|
||||
|
|
@ -749,7 +755,7 @@ body.is-phone .tugtile-ed-rich { padding-bottom: 55vh; }
|
|||
margin: 0 12px 8px;
|
||||
padding: 12px;
|
||||
border: 2px dashed var(--background-modifier-border);
|
||||
border-radius: var(--radius-m);
|
||||
border-radius: var(--radius-m); corner-shape: var(--corner);
|
||||
background: var(--background-secondary);
|
||||
color: var(--text-muted);
|
||||
font-weight: 600;
|
||||
|
|
@ -762,7 +768,7 @@ body.is-phone .tugtile-ed-rich { padding-bottom: 55vh; }
|
|||
flex: 0 0 auto;
|
||||
width: 1.6em;
|
||||
height: 1.6em;
|
||||
border-radius: var(--radius-s);
|
||||
border-radius: var(--radius-s); corner-shape: var(--corner);
|
||||
/* Opaque (translucent hover tint composited over the lane bg) so the vertical title retracting INTO the
|
||||
chevron during collapse/expand is fully masked — a see-through button would leak that text. */
|
||||
background: linear-gradient(var(--background-modifier-hover), var(--background-modifier-hover)), var(--background-secondary);
|
||||
|
|
@ -862,7 +868,7 @@ body.is-phone .tugtile-ed-rich { padding-bottom: 55vh; }
|
|||
gap: 8px;
|
||||
padding: 8px;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: var(--radius-m);
|
||||
border-radius: var(--radius-m); corner-shape: var(--corner);
|
||||
}
|
||||
.tugtile-archive-body {
|
||||
flex: 1;
|
||||
|
|
@ -886,7 +892,7 @@ body.is-phone .tugtile-ed-rich { padding-bottom: 55vh; }
|
|||
text-align: left; /* Match the add-card button (consistent left-aligned "+ label") */
|
||||
background: transparent;
|
||||
border: 1px dashed var(--background-modifier-border);
|
||||
border-radius: var(--radius-m);
|
||||
border-radius: var(--radius-m); corner-shape: var(--corner);
|
||||
color: var(--text-muted);
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
|
|
|
|||
Loading…
Reference in a new issue