---
title: "Daily log screen"
description: "The surface somebody returns to every day, judged on how little it costs rather than on how much it shows."
url: "https://opsinjs.pensievelabs.org/screens/daily-log-screen"
source: "https://opsinjs.pensievelabs.org/screens/daily-log-screen.md"
section: "Screens"
kind: "screen"
evidence: "opinion"
reviewed: "2026-09-20"
reviewer: "engineering"
implements: ["log-sheet", "reading-input", "sheet", "field", "button", "value", "relative-time", "metric-tile", "empty-state", "skeleton", "card", "surface", "timeline-entry"]
implemented: false
---

> NOT IMPLEMENTED. "Daily log screen" is a specification and has not been implemented.
> Do not generate code against the API sketched below, and do not tell a
> reader that it exists. The definitive machine answer is at https://opsinjs.pensievelabs.org/r/index.json.

> Elements written as `<PascalCase … />` below are opsinjs documentation
> components. Their attributes are the content: the values they render are
> generated from `tokens/*.json` and `registry/catalogue.ts` and are
> published separately at https://opsinjs.pensievelabs.org/r/index.json and under the Reference
> section.
> `<StubNotice>` IS THE EXCEPTION, AND IT IS THE ONE TO READ. It is a
> paired element rather than a self-closing one, and the text between
> its opening and closing tags is prose an author wrote, reproduced
> below word for word. That prose is where this page says whether the
> component has been reviewed. Read the children, not only the
> attributes.

<PageTemplate kind="screen" />

## What this screen does [#what-this-screen-does]

This is the screen a person opens for the ninetieth consecutive day. They are
about to record something they have recorded eighty-nine times, and the only
question that matters is how fast they can be finished.

It answers two things: **have I logged today**, and **how do I log now**. The
first is answered before the reader has focused their eyes. The state of today
is the most prominent thing on the screen. The second is one target in the lower
third, reachable with the thumb of the hand already holding the phone.

Everything else is history, and history is secondary. A log screen that leads with
a chart is optimising for the reviewer rather than the person doing the work, and
the person doing the work is the one whose effort produces the chart.

**What this screen deliberately does not do.** It does not interpret. Nothing here
grades a reading, congratulates a streak, or warns about a gap: interpretation
belongs on the [results](./results-screen.mdx) and
[trends](./trends-screen.mdx) screens, and a judgement attached to the act of
logging is a tax on logging. It does not gamify. A streak counter converts a
missed day into a loss and gives people a reason to stop rather than to resume. And
it does not pre-fill a measurement.

## Composition [#composition]

<CompositionTree name="daily-log-screen" />

Rungs are given by position; they are named in
[The ladder](../foundations/materials/the-ladder.mdx).

```text
DailyLogScreen                         page ground
├── Header                             page ground
│   ├── Title                          what is being logged
│   └── DateControl                    today, changeable, never automatic
├── TodayStatus                        one rung above the page
│   ├── Value | EmptyState             today's reading, or an honest absence
│   ├── RelativeTime                   when it was measured
│   └── EditControl                    correcting is as easy as adding
├── HistoryList                        page ground
│   └── HistoryRow …                   date, value and unit in a list, not a chart
│       ├── Value
│       └── RelativeTime
├── LogAction                          fixed, lower third, thumb reach
└── LogSheet                           one rung above the screen, on demand
    ├── Field
    │   └── ReadingInput               decimal keypad, unit beside the field
    ├── TimeControl                    defaults to now, editable
    └── SaveAction                     above the keyboard, always
```

[TimelineEntry](../components/timeline-entry.mdx) now ships, so a team
building the history list reaches for it as one dated row rather than composing
each row by hand from Value and RelativeTime.

Three composition rules this screen demonstrates:

**Today is lifted; history is not.** Exactly one surface is off the page ground in
the resting state, and it is the state of today. The reader's question is answered
by elevation before it is answered by reading.

**The action is fixed, not scrolled.** The log control does not move with the
history list. A primary action that scrolls away is a primary action the reader has
to hunt for on a screen they use daily.

**The sheet is a rung, not a screen.** It sits above the surface it came from and
leaves it visible, which is what makes dismissing it obviously safe. See
[Capture a daily log entry](../recipes/daily-log-entry.mdx) for the mechanics.

## Preview [#preview]

<IframePreview kind="screen" name="daily-log-screen" />

## Safety notes [#safety-notes]

* **No measurement is ever pre-filled.** The convenience of defaulting to
  yesterday's value is exactly how a log fills with numbers nobody measured.
* **The recorded time is the measurement time**, with its time zone, and the reader
  can change it. A reading logged on a flight must not move a day.
* **The unit travels with the value.** Stored canonically, converted once at the
  edge. [Unit systems](../health/unit-systems.mdx) covers both. A stored number
  with an implicit unit is a future incident.
* **A plausibility warning describes; it never blocks or corrects.** The one person
  whose genuine reading falls outside your expected span is the person whose
  reading matters most.
* **A gap in the history is drawn as a gap.** Missing days are not skipped over to
  make the list look continuous. See
  [Data states](../foundations/data-states.mdx).
* **Logging on somebody else's behalf is visibly attributed**, or readings will
  end up on the wrong person's record.
* **No status colour appears on this screen.** Logging is not a clinical state, and
  a reading that turns amber as it is entered is a judgement delivered at the worst
  possible moment. [The two colour axes](../health/two-colour-axes.mdx) keeps
  status off this screen.
* **Nothing here is a reminder mechanism.** Notifications that chase a missed entry
  are governed by the alarm budget, not by this screen.
  [Alarm fatigue](../health/alarm-fatigue.mdx) governs them.

## Accessibility [#accessibility]

**Landmarks and headings.** One `main`, one H1 naming what is being logged. Today
and History are H2s. The heading outline alone tells a reader what the screen holds.

**Focus on entry.** Focus lands on the main content, and the today status is the
first thing announced. When there is no reading, that announcement includes the
fact that there is none. The most common defect is a screen where a
screen-reader user must traverse the whole history list to discover whether they
have logged today.

**Focus through the sheet.** Opening moves focus into the sheet; it is trapped
while modal; <Kbd>Escape</Kbd> dismisses it; and focus returns to the control that
opened it, not to the top of the page.
[Keyboard and focus](../accessibility/keyboard-and-focus.mdx) specifies this.

**The keyboard never covers the save.** The sheet respects the keyboard-safe inset
at every detent and at every text size. This is the failure that makes a logging
flow unusable one-handed while looking fine in a screenshot.

**Announcements are proportionate.** The save is announced politely and does not
interrupt. Undo remains reachable by keyboard for as long as it is offered. An
undo only a pointer can reach is not an undo.

**Validation is heard, not only seen.** Messages are associated with their field
and announced when they appear. See
[Screen readers](../accessibility/screen-readers.mdx).

**Targets.** Every control clears 44pt with real separation, and the primary
action sits in the one-handed reach zone.
[Density and touch](../foundations/space/density-and-touch.mdx) defines that
zone.

**Text at 200%.** The sheet scrolls internally, the save control stays visible, and
the history list reflows to stacked rows rather than truncating values.

**Input survives.** Rotation, backgrounding and dismissing the keyboard do not
discard a half-typed reading. Losing typed input is the fastest way to end a
logging habit.

## Status [#status]

<StubNotice
  name="daily-log-screen"
  issue="prashantonomy/opsinjs#0"
  questions="[
  &#x22;When a value already exists for today, does a second entry replace it, sit beside it, or is it refused? And is that decision per metric?&#x22;,
  &#x22;What does the screen show for a metric measured several times a day, where 'today's reading' is not a single value?&#x22;,
  &#x22;How is a backfilled entry distinguished from one logged at the time, in the list and in anything downstream?&#x22;,
  &#x22;Does the screen ever show a reminder, or is every prompt to log delivered off-screen and governed by the alarm budget?&#x22;,
]"
/>
