Redo modern-style widgets in a "bold minimal" language, not just a reskin
The first modern-style rollout translated each widget's existing classic layout into HTML/CSS -- same gradient headers, same rounded-shadowed card, prettier chrome around an unchanged composition. This actually redesigns weather (current/daily), calendar (all four views), tasks, and battery: no card/shadow anywhere, a slim accent-colored rule instead of a full gradient banner (and only that rule dithers at the richer accent amplitude now, not the header text sitting on it), and a dominant hero value (temperature/percent) instead of a centered icon+number of equal weight. Padding and type sizes scale as a clamped proportion of widget size instead of fixed pixel values. Text and static/whiteboard are left alone -- text already had zero chrome and its styling is user content, not this system's to redesign; framed_image's card was already minimal. Direction was picked from three divergent mockups reviewed with the maintainer, then verified against the real render pipeline (actual Chromium render, actual ordered dithering, actual theme system) rather than just eyeballed -- that caught a day-section/month-grid divider color (#e2e6ec) that's nowhere near this panel's 6-color palette and was dithering to invisible white; fixed with a real black hairline in the one place (month view) that still needed one.
This commit is contained in:
@@ -1,19 +1,26 @@
|
||||
{% macro day_section(header, weather_entries, weather_size, unit_suffix, rows, more_count, row_h, body_size, title_size, accent_start, accent_end, header_h) %}
|
||||
{% macro day_section(header, weather_entries, weather_size, unit_suffix, rows, more_count, row_h, body_size, title_size, accent_start, header_h, accent_h) %}
|
||||
<div class="day-section">
|
||||
{#- Fixed height (not auto) -- every stacked day-section's header
|
||||
must be exactly this tall regardless of whether THIS particular
|
||||
day has a weather entry, or days with/without weather misalign
|
||||
where their event rows start (see calendar_week_horizontal's
|
||||
identical fix/reasoning). #}
|
||||
<div class="day-header" style="background: linear-gradient(135deg, {{ accent_start }} 0%, {{ accent_end }} 100%); font-size: {{ title_size }}px; height: {{ header_h }}px;">
|
||||
<div class="day-header-title">{{ header }}</div>
|
||||
{% if weather_entries %}
|
||||
<div class="day-weather-row" style="font-size: {{ weather_size }}px;">
|
||||
{% for we in weather_entries %}
|
||||
<div class="day-weather-entry"><span class="day-weather-icon" style="font-size: {{ weather_size * 1.3 }}px;">{{ we.emoji }}</span><span>{{ we.high }}°/{{ we.low }}°{{ unit_suffix }}</span></div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
identical fix/reasoning). Bold-minimal: a slim accent-colored
|
||||
rule (not a full gradient band) carries the theme identity --
|
||||
the header text itself is plain ink, dithered at the base
|
||||
amplitude like everything else, not the richer accent amplitude
|
||||
the old white-on-gradient text needed to stay legible. #}
|
||||
<div class="day-header" style="height: {{ header_h }}px;">
|
||||
<div class="accent-rule" style="height: {{ accent_h }}px; background: {{ accent_start }};"></div>
|
||||
<div class="day-header-row">
|
||||
<div class="day-header-title" style="font-size: {{ title_size }}px;">{{ header }}</div>
|
||||
{% if weather_entries %}
|
||||
<div class="day-weather-row" style="font-size: {{ weather_size }}px;">
|
||||
{% for we in weather_entries %}
|
||||
<div class="day-weather-entry"><span class="day-weather-icon" style="font-size: {{ weather_size * 1.3 }}px;">{{ we.emoji }}</span><span>{{ we.high }}°/{{ we.low }}°{{ unit_suffix }}</span></div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="day-rows">
|
||||
{% if not rows and not more_count %}
|
||||
|
||||
@@ -4,18 +4,9 @@
|
||||
@font-face { font-family: "ThemeFont"; src: url("file://{{ font_bold }}"); font-weight: 700; }
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; font-family: "ThemeFont", sans-serif; }
|
||||
body { width: {{ w }}px; height: {{ h }}px; background: #ffffff; }
|
||||
.card {
|
||||
width: {{ w - gutter * 2 }}px;
|
||||
height: {{ h - gutter * 2 }}px;
|
||||
margin: {{ gutter }}px;
|
||||
border-radius: {{ radius }}px;
|
||||
overflow: hidden;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
.wrap {
|
||||
width: {{ w }}px; height: {{ h }}px; padding: {{ pad }}px;
|
||||
display: flex; flex-direction: column; justify-content: space-between;
|
||||
}
|
||||
.icon-wrap { display: flex; align-items: center; }
|
||||
.icon-body {
|
||||
@@ -24,7 +15,6 @@
|
||||
border: {{ stroke }}px solid #000000;
|
||||
border-radius: {{ icon_radius }}px;
|
||||
padding: {{ stroke }}px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
.icon-fill {
|
||||
width: {{ fill_pct }}%;
|
||||
@@ -38,16 +28,19 @@
|
||||
background: #000000;
|
||||
border-radius: 0 {{ nub_radius }}px {{ nub_radius }}px 0;
|
||||
}
|
||||
.pct { font-weight: 700; font-size: {{ pct_size }}px; line-height: 1; color: {{ fill_color }}; }
|
||||
.line { font-weight: 400; font-size: {{ line_size }}px; line-height: 1; color: #5b6674; }
|
||||
.pct { font-weight: 700; font-size: {{ pct_size }}px; line-height: 0.85; color: {{ fill_color }}; letter-spacing: -0.02em; }
|
||||
.lines { margin-top: {{ line_gap }}px; }
|
||||
.line { font-weight: 400; font-size: {{ line_size }}px; line-height: 1.3; color: #5b6674; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="wrap">
|
||||
<div class="icon-wrap">
|
||||
<div class="icon-body"><div class="icon-fill"></div></div>
|
||||
<div class="icon-nub"></div>
|
||||
</div>
|
||||
<div class="pct">{{ percent }}%</div>
|
||||
{% for line in lines %}<div class="line">{{ line }}</div>{% endfor %}
|
||||
<div>
|
||||
<div class="pct">{{ percent }}%</div>
|
||||
<div class="lines">{% for line in lines %}<div class="line">{{ line }}</div>{% endfor %}</div>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
|
||||
@@ -4,33 +4,32 @@
|
||||
@font-face { font-family: "ThemeFont"; src: url("file://{{ font_bold }}"); font-weight: 700; }
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; font-family: "ThemeFont", sans-serif; }
|
||||
body { width: {{ w }}px; height: {{ h }}px; background: #ffffff; }
|
||||
.card {
|
||||
.wrap {
|
||||
width: {{ w - gutter * 2 }}px;
|
||||
height: {{ h - gutter * 2 }}px;
|
||||
margin: {{ gutter }}px;
|
||||
border-radius: {{ radius }}px;
|
||||
overflow: hidden;
|
||||
{% if shadow %}box-shadow: 0 4px 14px rgba(0, 20, 60, 0.2);{% endif %}
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.day-section { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
|
||||
.day-header { flex: 0 0 auto; color: #ffffff; font-weight: 700; line-height: 1.2; padding: 10px 16px; overflow: hidden; }
|
||||
.day-weather-row { display: flex; gap: 14px; margin-top: 6px; }
|
||||
.day-weather-entry { display: flex; align-items: center; gap: 4px; color: rgba(255,255,255,0.9); }
|
||||
.day-section { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; overflow: hidden; }
|
||||
.day-header { flex: 0 0 auto; display: flex; flex-direction: column; overflow: hidden; }
|
||||
.accent-rule { width: 100%; border-radius: 100px; }
|
||||
.day-header-row { flex: 1 1 auto; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-top: 6px; min-height: 0; }
|
||||
.day-header-title { font-weight: 700; color: #17233b; line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.day-weather-row { display: flex; gap: 14px; flex: 0 0 auto; }
|
||||
.day-weather-entry { display: flex; align-items: center; gap: 4px; color: #5b6674; }
|
||||
.day-weather-icon { line-height: 1; }
|
||||
.day-rows { flex: 1 1 auto; padding: 8px 14px; overflow: hidden; }
|
||||
.day-rows { flex: 1 1 auto; padding: 8px 0; overflow: hidden; }
|
||||
.day-row { display: flex; align-items: center; gap: 8px; }
|
||||
.day-chip { display: flex; height: 12px; width: 10px; border-radius: 3px; overflow: hidden; flex: 0 0 auto; }
|
||||
.day-chip span { flex: 1 1 0; }
|
||||
.day-time { color: #5b6674; flex: 0 0 auto; white-space: nowrap; }
|
||||
.day-time { color: #5b6674; flex: 0 0 auto; white-space: nowrap; font-variant-numeric: tabular-nums; }
|
||||
.day-summary { color: #17233b; line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.day-empty, .day-more { color: #5b6674; padding-top: 4px; }
|
||||
</style></head>
|
||||
<body>
|
||||
{% import "_calendar_day_section.html.jinja" as ds %}
|
||||
<div class="card">
|
||||
{{ ds.day_section(header, weather_entries, weather_size, unit_suffix, rows, more_count, row_h, body_size, title_size, accent_start, accent_end, header_h) }}
|
||||
<div class="wrap">
|
||||
{{ ds.day_section(header, weather_entries, weather_size, unit_suffix, rows, more_count, row_h, body_size, title_size, accent_start, header_h, accent_h) }}
|
||||
</div>
|
||||
</body></html>
|
||||
|
||||
@@ -4,22 +4,27 @@
|
||||
@font-face { font-family: "ThemeFont"; src: url("file://{{ font_bold }}"); font-weight: 700; }
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; font-family: "ThemeFont", sans-serif; }
|
||||
body { width: {{ w }}px; height: {{ h }}px; background: #ffffff; }
|
||||
.card {
|
||||
.wrap {
|
||||
width: {{ w - gutter * 2 }}px;
|
||||
height: {{ h - gutter * 2 }}px;
|
||||
margin: {{ gutter }}px;
|
||||
border-radius: {{ radius }}px;
|
||||
overflow: hidden;
|
||||
{% if shadow %}box-shadow: 0 4px 14px rgba(0, 20, 60, 0.2);{% endif %}
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.weekday-row { display: flex; flex: 0 0 auto; background: {{ accent_start }}; }
|
||||
.weekday-cell { flex: 1 1 0; color: #ffffff; font-weight: 700; font-size: {{ header_size }}px; text-align: center; padding: 4px 0; }
|
||||
.weeks { flex: 1 1 auto; display: flex; flex-direction: column; }
|
||||
.accent-rule { flex: 0 0 auto; width: 100%; height: {{ accent_h }}px; border-radius: 100px; background: {{ accent_start }}; }
|
||||
.weekday-row { display: flex; flex: 0 0 auto; margin-top: 6px; }
|
||||
.weekday-cell { flex: 1 1 0; color: #17233b; font-weight: 700; font-size: {{ header_size }}px; text-align: center; padding: 4px 0; }
|
||||
.weeks { flex: 1 1 auto; display: flex; flex-direction: column; margin-top: 2px; }
|
||||
.week-row { flex: 1 1 0; display: flex; }
|
||||
.day-cell { flex: 1 1 0; border: 1px solid #e2e6ec; padding: 4px; min-width: 0; overflow: hidden; }
|
||||
{#- A real palette color (pure black), not a pale gray -- this panel's
|
||||
6-color palette has no gray to dither toward, so #e2e6ec-style
|
||||
"hairlines" don't survive at all (confirmed by sampling actual
|
||||
rendered pixels: every one came back pure white). Horizontal
|
||||
rules only, between week rows -- enough for the grid to scan
|
||||
top-to-bottom without boxing every single day cell, which read
|
||||
more like the old structured-dashboard mockup than bold-minimal. #}
|
||||
.week-row + .week-row { border-top: 1px solid #000000; }
|
||||
.day-cell { flex: 1 1 0; padding: 4px; min-width: 0; overflow: hidden; }
|
||||
{#- Bold everywhere, including out-of-month -- de-emphasis is via
|
||||
smaller size only, not weight or a gray color. Regular-weight and
|
||||
gray text are both individually fragile under Bayer ordered
|
||||
@@ -40,7 +45,8 @@
|
||||
.dot-more { font-size: {{ day_size * 0.8 }}px; color: #5b6674; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="wrap">
|
||||
<div class="accent-rule"></div>
|
||||
<div class="weekday-row">
|
||||
{% for name in day_names %}<div class="weekday-cell">{{ name }}</div>{% endfor %}
|
||||
</div>
|
||||
|
||||
@@ -4,36 +4,39 @@
|
||||
@font-face { font-family: "ThemeFont"; src: url("file://{{ font_bold }}"); font-weight: 700; }
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; font-family: "ThemeFont", sans-serif; }
|
||||
body { width: {{ w }}px; height: {{ h }}px; background: #ffffff; }
|
||||
.card {
|
||||
.wrap {
|
||||
width: {{ w - gutter * 2 }}px;
|
||||
height: {{ h - gutter * 2 }}px;
|
||||
margin: {{ gutter }}px;
|
||||
border-radius: {{ radius }}px;
|
||||
overflow: hidden;
|
||||
{% if shadow %}box-shadow: 0 4px 14px rgba(0, 20, 60, 0.2);{% endif %}
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.day-section { display: flex; flex-direction: column; flex: 1 1 0; min-height: 0; overflow: hidden; }
|
||||
.day-section + .day-section { border-top: 1px solid #e2e6ec; }
|
||||
.day-header { flex: 0 0 auto; color: #ffffff; font-weight: 700; line-height: 1.2; padding: 8px 16px; overflow: hidden; }
|
||||
.day-weather-row { display: flex; gap: 14px; margin-top: 4px; }
|
||||
.day-weather-entry { display: flex; align-items: center; gap: 4px; color: rgba(255,255,255,0.9); }
|
||||
{#- No divider line -- #e2e6ec was invisible on this panel's 6-color
|
||||
palette anyway (no gray to dither toward, confirmed by sampling
|
||||
rendered pixels), and the accent rule + margin at the top of the
|
||||
next section already reads as a clear boundary without one. #}
|
||||
.day-section + .day-section { margin-top: 8px; }
|
||||
.day-header { flex: 0 0 auto; display: flex; flex-direction: column; overflow: hidden; }
|
||||
.accent-rule { width: 100%; border-radius: 100px; }
|
||||
.day-header-row { flex: 1 1 auto; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-top: 4px; min-height: 0; }
|
||||
.day-header-title { font-weight: 700; color: #17233b; line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.day-weather-row { display: flex; gap: 12px; flex: 0 0 auto; }
|
||||
.day-weather-entry { display: flex; align-items: center; gap: 4px; color: #5b6674; }
|
||||
.day-weather-icon { line-height: 1; }
|
||||
.day-rows { flex: 1 1 auto; padding: 6px 14px; overflow: hidden; }
|
||||
.day-rows { flex: 1 1 auto; padding: 4px 0; overflow: hidden; }
|
||||
.day-row { display: flex; align-items: center; gap: 8px; }
|
||||
.day-chip { display: flex; height: 12px; width: 10px; border-radius: 3px; overflow: hidden; flex: 0 0 auto; }
|
||||
.day-chip span { flex: 1 1 0; }
|
||||
.day-time { color: #5b6674; flex: 0 0 auto; white-space: nowrap; }
|
||||
.day-time { color: #5b6674; flex: 0 0 auto; white-space: nowrap; font-variant-numeric: tabular-nums; }
|
||||
.day-summary { color: #17233b; line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.day-empty, .day-more { color: #5b6674; padding-top: 2px; }
|
||||
</style></head>
|
||||
<body>
|
||||
{% import "_calendar_day_section.html.jinja" as ds %}
|
||||
<div class="card">
|
||||
<div class="wrap">
|
||||
{% for day in days %}
|
||||
{{ ds.day_section(day.header, day.weather_entries, weather_size, unit_suffix, day.rows, day.more_count, row_h, body_size, title_size, accent_start, accent_end, header_h) }}
|
||||
{{ ds.day_section(day.header, day.weather_entries, weather_size, unit_suffix, day.rows, day.more_count, row_h, body_size, title_size, accent_start, header_h, accent_h) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</body></html>
|
||||
|
||||
@@ -4,32 +4,36 @@
|
||||
@font-face { font-family: "ThemeFont"; src: url("file://{{ font_bold }}"); font-weight: 700; }
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; font-family: "ThemeFont", sans-serif; }
|
||||
body { width: {{ w }}px; height: {{ h }}px; background: #ffffff; }
|
||||
.card {
|
||||
.wrap {
|
||||
width: {{ w - gutter * 2 }}px;
|
||||
height: {{ h - gutter * 2 }}px;
|
||||
margin: {{ gutter }}px;
|
||||
border-radius: {{ radius }}px;
|
||||
overflow: hidden;
|
||||
{% if shadow %}box-shadow: 0 4px 14px rgba(0, 20, 60, 0.2);{% endif %}
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.accent-rule { flex: 0 0 auto; width: 100%; height: {{ accent_h }}px; border-radius: 100px; background: {{ accent_start }}; }
|
||||
.cols { flex: 1 1 auto; display: flex; margin-top: 6px; min-height: 0; }
|
||||
.col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; }
|
||||
.col + .col { border-left: 1px solid #e2e6ec; }
|
||||
{#- No divider line -- #e2e6ec was invisible on this panel's 6-color
|
||||
palette anyway (no gray to dither toward, confirmed by sampling
|
||||
rendered pixels); the shared accent rule above already frames the
|
||||
whole week as one unit, and each column's own label anchors it. #}
|
||||
.col + .col { margin-left: 4px; }
|
||||
.col-header {
|
||||
/* Fixed height (not auto) -- every column must be exactly this tall
|
||||
regardless of whether THIS particular day has a weather entry, or
|
||||
columns with/without weather misalign their event rows to
|
||||
different starting Y positions across the week grid. */
|
||||
{#- Fixed height (not auto) -- every column must be exactly this tall
|
||||
regardless of whether THIS particular day has a weather entry, or
|
||||
columns with/without weather misalign their event rows to
|
||||
different starting Y positions across the week grid. #}
|
||||
height: {{ header_h }}px;
|
||||
flex: 0 0 auto;
|
||||
background: linear-gradient(135deg, {{ accent_start }} 0%, {{ accent_end }} 100%);
|
||||
color: #ffffff; font-weight: 700; font-size: {{ header_size }}px;
|
||||
padding: 6px 6px;
|
||||
padding: 2px 6px 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.col-header .label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.col-weather { display: flex; align-items: center; gap: 3px; color: rgba(255,255,255,0.9); font-size: {{ weather_size }}px; margin-top: 2px; }
|
||||
.col-header .label {
|
||||
font-weight: 700; color: #17233b; font-size: {{ header_size }}px;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
}
|
||||
.col-weather { display: flex; align-items: center; gap: 3px; color: #5b6674; font-size: {{ weather_size }}px; margin-top: 2px; }
|
||||
.col-rows { flex: 1 1 auto; padding: 4px; overflow: hidden; }
|
||||
.col-row { display: flex; align-items: center; gap: 4px; min-width: 0; }
|
||||
.col-chip { width: 7px; height: 7px; border-radius: 2px; flex: 0 0 auto; }
|
||||
@@ -41,20 +45,23 @@
|
||||
.col-more { font-size: {{ chip_size }}px; color: #5b6674; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="card">
|
||||
{% for col in cols %}
|
||||
<div class="col">
|
||||
<div class="col-header">
|
||||
<div class="label">{{ col.label }}</div>
|
||||
{% if col.weather %}<div class="col-weather"><span>{{ col.weather.emoji }}</span><span>{{ col.weather.high }}°/{{ col.weather.low }}°{{ unit_suffix }}</span></div>{% endif %}
|
||||
<div class="wrap">
|
||||
<div class="accent-rule"></div>
|
||||
<div class="cols">
|
||||
{% for col in cols %}
|
||||
<div class="col">
|
||||
<div class="col-header">
|
||||
<div class="label">{{ col.label }}</div>
|
||||
{% if col.weather %}<div class="col-weather"><span>{{ col.weather.emoji }}</span><span>{{ col.weather.high }}°/{{ col.weather.low }}°{{ unit_suffix }}</span></div>{% endif %}
|
||||
</div>
|
||||
<div class="col-rows">
|
||||
{% for row in col.rows %}
|
||||
<div class="col-row"><div class="col-chip" style="background:{{ row.color }};"></div><div class="col-summary">{{ row.summary }}</div></div>
|
||||
{% endfor %}
|
||||
{% if col.more_count %}<div class="col-more">+{{ col.more_count }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-rows">
|
||||
{% for row in col.rows %}
|
||||
<div class="col-row"><div class="col-chip" style="background:{{ row.color }};"></div><div class="col-summary">{{ row.summary }}</div></div>
|
||||
{% endfor %}
|
||||
{% if col.more_count %}<div class="col-more">+{{ col.more_count }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
|
||||
@@ -4,27 +4,21 @@
|
||||
@font-face { font-family: "ThemeFont"; src: url("file://{{ font_bold }}"); font-weight: 700; }
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; font-family: "ThemeFont", sans-serif; }
|
||||
body { width: {{ w }}px; height: {{ h }}px; background: #ffffff; }
|
||||
.card {
|
||||
.wrap {
|
||||
width: {{ w - gutter * 2 }}px;
|
||||
height: {{ h - gutter * 2 }}px;
|
||||
margin: {{ gutter }}px;
|
||||
border-radius: {{ radius }}px;
|
||||
overflow: hidden;
|
||||
{% if shadow %}box-shadow: 0 4px 14px rgba(0, 20, 60, 0.2);{% endif %}
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.header {
|
||||
height: {{ header_h }}px;
|
||||
flex: 0 0 auto;
|
||||
background: linear-gradient(135deg, {{ accent_start }} 0%, {{ accent_end }} 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 16px;
|
||||
.header { flex: 0 0 auto; height: {{ header_h }}px; display: flex; flex-direction: column; overflow: hidden; }
|
||||
.accent-rule { width: 100%; height: {{ accent_h }}px; border-radius: 100px; background: {{ accent_start }}; }
|
||||
.title {
|
||||
flex: 1 1 auto; display: flex; align-items: center;
|
||||
color: #17233b; font-weight: 700; font-size: {{ title_size }}px; line-height: 1;
|
||||
padding-top: 4px;
|
||||
}
|
||||
.header .title { color: #ffffff; font-weight: 700; font-size: {{ title_size }}px; line-height: 1; }
|
||||
.rows { flex: 1 1 auto; padding: 8px 14px; overflow: hidden; }
|
||||
.rows { flex: 1 1 auto; padding-top: 4px; overflow: hidden; }
|
||||
.row { display: flex; align-items: center; gap: 8px; height: {{ row_h }}px; }
|
||||
.chip { display: flex; height: 12px; width: 10px; border-radius: 3px; overflow: hidden; flex: 0 0 auto; }
|
||||
.chip span { flex: 1 1 0; }
|
||||
@@ -33,7 +27,7 @@
|
||||
border: 2px solid #17233b;
|
||||
}
|
||||
.box.done { border-color: {{ accent_start }}; background: {{ accent_start }}; }
|
||||
.due { font-size: {{ body_size }}px; color: #5b6674; flex: 0 0 auto; white-space: nowrap; }
|
||||
.due { font-size: {{ body_size }}px; color: #5b6674; flex: 0 0 auto; white-space: nowrap; font-variant-numeric: tabular-nums; }
|
||||
.summary {
|
||||
font-size: {{ body_size }}px; color: #17233b; line-height: 1.2;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
@@ -42,8 +36,11 @@
|
||||
.more { font-size: {{ body_size }}px; color: #5b6674; padding-top: 2px; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="header"><div class="title">{{ title }}</div></div>
|
||||
<div class="wrap">
|
||||
<div class="header">
|
||||
<div class="accent-rule"></div>
|
||||
<div class="title">{{ title }}</div>
|
||||
</div>
|
||||
<div class="rows">
|
||||
{% if not rows %}
|
||||
<div class="empty">Nothing outstanding</div>
|
||||
|
||||
@@ -4,27 +4,34 @@
|
||||
@font-face { font-family: "ThemeFont"; src: url("file://{{ font_bold }}"); font-weight: 700; }
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; font-family: "ThemeFont", sans-serif; }
|
||||
body { width: {{ w }}px; height: {{ h }}px; background: #ffffff; }
|
||||
.card {
|
||||
width: {{ w - gutter * 2 }}px;
|
||||
height: {{ h - gutter * 2 }}px;
|
||||
margin: {{ gutter }}px;
|
||||
border-radius: {{ radius }}px;
|
||||
overflow: hidden;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
.wrap {
|
||||
width: {{ w }}px; height: {{ h }}px; padding: {{ pad }}px;
|
||||
display: flex; flex-direction: column; justify-content: space-between;
|
||||
}
|
||||
.icon { font-size: {{ icon_size }}px; line-height: 1; filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.18)); }
|
||||
.temp { font-weight: 700; font-size: {{ temp_size }}px; color: #17233b; }
|
||||
.city { font-weight: 400; font-size: {{ label_size }}px; color: #5b6674; }
|
||||
.top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
|
||||
.city {
|
||||
flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
font-weight: 700; font-size: {{ city_size }}px; line-height: 1.2;
|
||||
letter-spacing: 0.12em; text-transform: uppercase; color: #5b6674;
|
||||
}
|
||||
.icon { flex: 0 0 auto; font-size: {{ icon_size }}px; line-height: 1; }
|
||||
.temp-row { display: flex; align-items: flex-start; }
|
||||
.temp {
|
||||
font-weight: 700; font-size: {{ temp_size }}px; line-height: 0.85;
|
||||
color: #17233b; letter-spacing: -0.03em;
|
||||
}
|
||||
.deg { font-weight: 400; font-size: {{ deg_size }}px; line-height: 1.3; color: #5b6674; }
|
||||
.cond { font-weight: 400; font-size: {{ cond_size }}px; color: #5b6674; margin-top: {{ (pad * 0.25) | round(0, 'floor') }}px; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="icon">{{ emoji }}</div>
|
||||
<div class="temp">{{ temp }}°{{ unit_suffix }}</div>
|
||||
{% if city_label %}<div class="city">{{ city_label }}</div>{% endif %}
|
||||
<div class="wrap">
|
||||
<div class="top">
|
||||
{% if city_label %}<div class="city">{{ city_label }}</div>{% else %}<div></div>{% endif %}
|
||||
<div class="icon">{{ emoji }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="temp-row"><div class="temp">{{ temp }}</div><div class="deg">°{{ unit_suffix }}</div></div>
|
||||
{% if condition %}<div class="cond">{{ condition }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
|
||||
@@ -4,46 +4,40 @@
|
||||
@font-face { font-family: "ThemeFont"; src: url("file://{{ font_bold }}"); font-weight: 700; }
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; font-family: "ThemeFont", sans-serif; }
|
||||
body { width: {{ w }}px; height: {{ h }}px; background: #ffffff; }
|
||||
.card {
|
||||
width: {{ w - gutter * 2 }}px;
|
||||
height: {{ h - gutter * 2 }}px;
|
||||
margin: {{ gutter }}px;
|
||||
border-radius: {{ radius }}px;
|
||||
overflow: hidden;
|
||||
{% if shadow %}box-shadow: 0 4px 14px rgba(0, 20, 60, 0.25);{% endif %}
|
||||
background: #ffffff;
|
||||
.wrap { width: {{ w }}px; height: {{ h }}px; padding: {{ pad }}px; display: flex; flex-direction: column; }
|
||||
.accent-bar {
|
||||
flex: 0 0 auto; height: {{ accent_h }}px; width: 100%;
|
||||
border-radius: {{ (accent_h / 2) | round(0, 'floor') }}px;
|
||||
background: linear-gradient(90deg, {{ accent_start }} 0%, {{ accent_end }} 100%);
|
||||
}
|
||||
.header {
|
||||
height: {{ header_h }}px;
|
||||
background: linear-gradient(135deg, {{ accent_start }} 0%, {{ accent_end }} 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 16px;
|
||||
.city {
|
||||
flex: 0 0 auto; margin-top: 6px; font-weight: 700; font-size: {{ city_size }}px;
|
||||
letter-spacing: 0.12em; text-transform: uppercase; color: #5b6674;
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
|
||||
}
|
||||
.header .title { color: #ffffff; font-weight: 700; font-size: {{ title_size }}px; }
|
||||
.body { display: flex; height: calc(100% - {{ header_h }}px); padding: 12px 8px; }
|
||||
.col {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
.days { flex: 1 1 auto; display: flex; align-items: center; gap: {{ col_gap }}px; }
|
||||
.col { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; }
|
||||
.day-label {
|
||||
font-weight: 700; font-size: {{ day_label_size }}px; letter-spacing: 0.06em;
|
||||
text-transform: uppercase; color: #5b6674;
|
||||
}
|
||||
.day { font-weight: 600; font-size: {{ label_size }}px; color: #17233b; }
|
||||
.icon { font-size: {{ icon_size }}px; line-height: 1; }
|
||||
.temps { font-weight: 700; font-size: {{ label_size }}px; color: #17233b; }
|
||||
.temps .low { color: #6b7788; font-weight: 400; }
|
||||
.temps { display: flex; align-items: baseline; gap: 3px; }
|
||||
.high { font-weight: 700; font-size: {{ high_size }}px; line-height: 1; color: #17233b; }
|
||||
.low { font-weight: 400; font-size: {{ low_size }}px; line-height: 1; color: #5b6674; }
|
||||
</style></head>
|
||||
<body>
|
||||
<div class="card">
|
||||
{% if city_label %}<div class="header"><div class="title">{{ city_label }}</div></div>{% endif %}
|
||||
<div class="body">
|
||||
<div class="wrap">
|
||||
{% if city_label %}
|
||||
<div class="accent-bar"></div>
|
||||
<div class="city">{{ city_label }}</div>
|
||||
{% endif %}
|
||||
<div class="days">
|
||||
{% for d in days %}
|
||||
<div class="col">
|
||||
<div class="day">{{ d.label }}</div>
|
||||
<div class="day-label">{{ d.label }}</div>
|
||||
<div class="icon">{{ d.emoji }}</div>
|
||||
<div class="temps">{{ d.high }}°<span class="low">/{{ d.low }}°{{ unit_suffix }}</span></div>
|
||||
<div class="temps"><div class="high">{{ d.high }}°</div><div class="low">{{ d.low }}°{{ unit_suffix }}</div></div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user